Stock Prediction Sample¶

Introduction¶

This notebook is designed to be self-guided, broken out into a number of steps to help illustrate the process of developing a ML model.

In [1]:
!pip install prophet
import pyspark.sql.functions as F
from pyspark.sql.types import *
StatementMeta(, 969b99e8-3fbb-4fd8-83d4-d90942f1c689, 3, Finished, Available)
Collecting prophet
  Downloading prophet-1.1.5-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (14.4 MB)
     ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 14.4/14.4 MB 87.9 MB/s eta 0:00:0000:0100:01
Collecting cmdstanpy>=1.0.4 (from prophet)
  Downloading cmdstanpy-1.2.0-py3-none-any.whl (93 kB)
     ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 93.0/93.0 kB 48.0 MB/s eta 0:00:00
Requirement already satisfied: numpy>=1.15.4 in /home/trusted-service-user/cluster-env/trident_env/lib/python3.10/site-packages (from prophet) (1.24.3)
Requirement already satisfied: matplotlib>=2.0.0 in /home/trusted-service-user/cluster-env/trident_env/lib/python3.10/site-packages (from prophet) (3.7.2)
Requirement already satisfied: pandas>=1.0.4 in /home/trusted-service-user/cluster-env/trident_env/lib/python3.10/site-packages (from prophet) (2.0.3)
Requirement already satisfied: holidays>=0.25 in /home/trusted-service-user/cluster-env/trident_env/lib/python3.10/site-packages (from prophet) (0.35)
Requirement already satisfied: tqdm>=4.36.1 in /home/trusted-service-user/cluster-env/trident_env/lib/python3.10/site-packages (from prophet) (4.66.1)
Requirement already satisfied: importlib-resources in /home/trusted-service-user/cluster-env/trident_env/lib/python3.10/site-packages (from prophet) (6.1.0)
Collecting stanio~=0.3.0 (from cmdstanpy>=1.0.4->prophet)
  Downloading stanio-0.3.0-py3-none-any.whl (6.2 kB)
Requirement already satisfied: python-dateutil in /home/trusted-service-user/cluster-env/trident_env/lib/python3.10/site-packages (from holidays>=0.25->prophet) (2.8.2)
Requirement already satisfied: contourpy>=1.0.1 in /home/trusted-service-user/cluster-env/trident_env/lib/python3.10/site-packages (from matplotlib>=2.0.0->prophet) (1.1.1)
Requirement already satisfied: cycler>=0.10 in /home/trusted-service-user/cluster-env/trident_env/lib/python3.10/site-packages (from matplotlib>=2.0.0->prophet) (0.12.1)
Requirement already satisfied: fonttools>=4.22.0 in /home/trusted-service-user/cluster-env/trident_env/lib/python3.10/site-packages (from matplotlib>=2.0.0->prophet) (4.43.1)
Requirement already satisfied: kiwisolver>=1.0.1 in /home/trusted-service-user/cluster-env/trident_env/lib/python3.10/site-packages (from matplotlib>=2.0.0->prophet) (1.4.5)
Requirement already satisfied: packaging>=20.0 in /home/trusted-service-user/cluster-env/trident_env/lib/python3.10/site-packages (from matplotlib>=2.0.0->prophet) (23.2)
Requirement already satisfied: pillow>=6.2.0 in /home/trusted-service-user/cluster-env/trident_env/lib/python3.10/site-packages (from matplotlib>=2.0.0->prophet) (10.0.1)
Requirement already satisfied: pyparsing<3.1,>=2.3.1 in /home/trusted-service-user/cluster-env/trident_env/lib/python3.10/site-packages (from matplotlib>=2.0.0->prophet) (3.0.9)
Requirement already satisfied: pytz>=2020.1 in /home/trusted-service-user/cluster-env/trident_env/lib/python3.10/site-packages (from pandas>=1.0.4->prophet) (2023.3.post1)
Requirement already satisfied: tzdata>=2022.1 in /home/trusted-service-user/cluster-env/trident_env/lib/python3.10/site-packages (from pandas>=1.0.4->prophet) (2023.3)
Requirement already satisfied: six>=1.5 in /home/trusted-service-user/cluster-env/trident_env/lib/python3.10/site-packages (from python-dateutil->holidays>=0.25->prophet) (1.16.0)
Installing collected packages: stanio, cmdstanpy, prophet
Successfully installed cmdstanpy-1.2.0 prophet-1.1.5 stanio-0.3.0
In [2]:
# configuration for downloads and stock symbol to analyze

# url to source tar file
FULL_URL = "https://fabricrealtimelab.blob.core.windows.net/public/AbboCost_Stock_History/stockhistory-2023-2024.tgz?sp=r&st=2023-11-26T23:59:09Z&se=2027-11-27T07:59:09Z&spr=https&sv=2022-11-02&sr=b&sig=70w%2BT6ZVGpdTd6YJr%2FzPhKUFk9JYJ2ezu6%2BBBr9ahxc%3D"
# lakehouse location -- assumes default lakehouse
LAKEHOUSE_FOLDER = "/lakehouse/default"

# filename and data folders
TAR_FILE_NAME = "stockhistory-2023-2024.tgz"
DATA_FOLDER = "Files/stockhistory/raw"

TAR_FILE_PATH = f"/{LAKEHOUSE_FOLDER}/{DATA_FOLDER}/tar/"
CSV_FILE_PATH = f"/{LAKEHOUSE_FOLDER}/{DATA_FOLDER}/csv/"

# specify the stock symbol to analyze - WHO, WHAT, IDK, WHY, BCUZ, TMRW, TDY, IDGD
# recommended: WHO, BCUZ, IDGD

# STOCK_SYMBOL = "IDGD"
# STOCK_SYMBOL = "BCUZ"
STOCK_SYMBOL = "WHO"
StatementMeta(, 969b99e8-3fbb-4fd8-83d4-d90942f1c689, 4, Finished, Available)

Step 1: Download the stock history source data files¶

Normally, this data would be ingested continuously into our lakehouse. In the interest of time, we've generated enough data to train from and do some experimentation. This was generated with the same engine (https://aka.ms/fabricrealtimelab); the stock generator is largely random and will vary by installation, but there are certain trends that should be present.

The cell will check for the data and only download/extract if the data does not exist.

In [3]:
import os

if not os.path.exists(LAKEHOUSE_FOLDER):
    # add a lakehouse if the notebook has no default lakehouse
    # a new notebook will not link to any lakehouse by default
    raise FileNotFoundError(
        "Lakehouse not found, please add a lakehouse for the notebook."
    )
else:
    # verify whether or not the required files are already in the lakehouse, and if not, download and unzip
    if not os.path.exists(f"{TAR_FILE_PATH}{TAR_FILE_NAME}"):
        os.makedirs(TAR_FILE_PATH, exist_ok=True)
        os.system(f"wget '{FULL_URL}' -O {TAR_FILE_PATH}{TAR_FILE_NAME}")

        #todo: better file checking
        os.makedirs(CSV_FILE_PATH, exist_ok=True)
        os.system(f"tar -zxvf {TAR_FILE_PATH}{TAR_FILE_NAME} -C {CSV_FILE_PATH}")
StatementMeta(, 969b99e8-3fbb-4fd8-83d4-d90942f1c689, 5, Finished, Available)
--2023-11-28 19:35:01--  https://fabricrealtimelab.blob.core.windows.net/public/AbboCost_Stock_History/stockhistory-2023-2024.tgz?sp=r&st=2023-11-26T23:59:09Z&se=2027-11-27T07:59:09Z&spr=https&sv=2022-11-02&sr=b&sig=70w%2BT6ZVGpdTd6YJr%2FzPhKUFk9JYJ2ezu6%2BBBr9ahxc%3D
Resolving fabricrealtimelab.blob.core.windows.net... 52.239.235.100
Connecting to fabricrealtimelab.blob.core.windows.net|52.239.235.100|:443... connected.
HTTP request sent, awaiting response... 200 OK
Length: 49453874 (47M) [application/x-compressed]
Saving to: ‘//lakehouse/default/Files/stockhistory/raw/tar/stockhistory-2023-2024.tgz’

     0K .......... .......... .......... .......... ..........  0%  593K 81s
    50K .......... .......... .......... .......... ..........  0% 1.17M 61s
   100K .......... .......... .......... .......... ..........  0% 1.17M 54s
   150K .......... .......... .......... .......... ..........  0% 48.0M 41s
   200K .......... .......... .......... .......... ..........  0% 1.18M 40s
   250K .......... .......... .......... .......... ..........  0% 65.5M 34s
   300K .......... .......... .......... .......... ..........  0% 1.19M 35s
   350K .......... .......... .......... .......... ..........  0% 50.0M 30s
   400K .......... .......... .......... .......... ..........  0% 67.0M 27s
   450K .......... .......... .......... .......... ..........  1% 1.22M 28s
   500K .......... .......... .......... .......... ..........  1% 64.6M 26s
   550K .......... .......... .......... .......... ..........  1% 60.5M 23s
   600K .......... .......... .......... .......... ..........  1% 75.1M 22s
   650K .......... .......... .......... .......... ..........  1% 1.22M 23s
   700K .......... .......... .......... .......... ..........  1% 75.3M 21s
   750K .......... .......... .......... .......... ..........  1% 68.6M 20s
   800K .......... .......... .......... .......... ..........  1% 80.5M 19s
   850K .......... .......... .......... .......... ..........  1% 1.22M 20s
   900K .......... .......... .......... .......... ..........  1% 72.6M 19s
   950K .......... .......... .......... .......... ..........  2% 67.1M 18s
  1000K .......... .......... .......... .......... ..........  2% 86.3M 17s
  1050K .......... .......... .......... .......... ..........  2% 56.5M 16s
  1100K .......... .......... .......... .......... ..........  2% 77.5M 16s
  1150K .......... .......... .......... .......... ..........  2% 1.25M 17s
  1200K .......... .......... .......... .......... ..........  2% 71.3M 16s
  1250K .......... .......... .......... .......... ..........  2% 71.4M 15s
  1300K .......... .......... .......... .......... ..........  2% 76.5M 15s
  1350K .......... .......... .......... .......... ..........  2% 68.3M 14s
  1400K .......... .......... .......... .......... ..........  3% 71.5M 14s
  1450K .......... .......... .......... .......... ..........  3% 1.27M 14s
  1500K .......... .......... .......... .......... ..........  3% 66.1M 14s
  1550K .......... .......... .......... .......... ..........  3% 63.6M 14s
  1600K .......... .......... .......... .......... ..........  3% 73.7M 13s
  1650K .......... .......... .......... .......... ..........  3% 72.7M 13s
  1700K .......... .......... .......... .......... ..........  3% 70.2M 12s
  1750K .......... .......... .......... .......... ..........  3% 63.4M 12s
  1800K .......... .......... .......... .......... ..........  3% 1.30M 13s
  1850K .......... .......... .......... .......... ..........  3% 63.6M 12s
  1900K .......... .......... .......... .......... ..........  4% 67.5M 12s
  1950K .......... .......... .......... .......... ..........  4% 57.1M 12s
  2000K .......... .......... .......... .......... ..........  4% 62.1M 11s
  2050K .......... .......... .......... .......... ..........  4% 62.8M 11s
  2100K .......... .......... .......... .......... ..........  4% 66.5M 11s
  2150K .......... .......... .......... .......... ..........  4% 57.8M 11s
  2200K .......... .......... .......... .......... ..........  4% 75.2M 10s
  2250K .......... .......... .......... .......... ..........  4% 68.8M 10s
  2300K .......... .......... .......... .......... ..........  4% 1.38M 11s
  2350K .......... .......... .......... .......... ..........  4% 52.8M 10s
  2400K .......... .......... .......... .......... ..........  5% 71.9M 10s
  2450K .......... .......... .......... .......... ..........  5% 74.0M 10s
  2500K .......... .......... .......... .......... ..........  5% 76.1M 10s
  2550K .......... .......... .......... .......... ..........  5% 60.4M 10s
  2600K .......... .......... .......... .......... ..........  5% 77.0M 9s
  2650K .......... .......... .......... .......... ..........  5% 76.7M 9s
  2700K .......... .......... .......... .......... ..........  5% 77.3M 9s
  2750K .......... .......... .......... .......... ..........  5% 65.7M 9s
  2800K .......... .......... .......... .......... ..........  5% 1.39M 9s
  2850K .......... .......... .......... .......... ..........  6% 64.3M 9s
  2900K .......... .......... .......... .......... ..........  6% 68.6M 9s
  2950K .......... .......... .......... .......... ..........  6% 64.9M 9s
  3000K .......... .......... .......... .......... ..........  6% 85.0M 9s
  3050K .......... .......... .......... .......... ..........  6% 74.8M 9s
  3100K .......... .......... .......... .......... ..........  6% 73.3M 8s
  3150K .......... .......... .......... .......... ..........  6% 61.6M 8s
  3200K .......... .......... .......... .......... ..........  6% 70.9M 8s
  3250K .......... .......... .......... .......... ..........  6% 71.5M 8s
  3300K .......... .......... .......... .......... ..........  6% 76.8M 8s
  3350K .......... .......... .......... .......... ..........  7% 63.5M 8s
  3400K .......... .......... .......... .......... ..........  7% 74.4M 8s
  3450K .......... .......... .......... .......... ..........  7% 72.6M 8s
  3500K .......... .......... .......... .......... ..........  7% 1.46M 8s
  3550K .......... .......... .......... .......... ..........  7% 54.7M 8s
  3600K .......... .......... .......... .......... ..........  7% 74.4M 8s
  3650K .......... .......... .......... .......... ..........  7% 72.1M 8s
  3700K .......... .......... .......... .......... ..........  7% 76.4M 8s
  3750K .......... .......... .......... .......... ..........  7% 62.9M 7s
  3800K .......... .......... .......... .......... ..........  7% 73.8M 7s
  3850K .......... .......... .......... .......... ..........  8% 74.0M 7s
  3900K .......... .......... .......... .......... ..........  8% 65.4M 7s
  3950K .......... .......... .......... .......... ..........  8% 60.9M 7s
  4000K .......... .......... .......... .......... ..........  8% 77.2M 7s
  4050K .......... .......... .......... .......... ..........  8% 1.06M 7s
  4100K .......... .......... .......... .......... ..........  8% 94.1M 7s
  4150K .......... .......... .......... .......... ..........  8%  107M 7s
  4200K .......... .......... .......... .......... ..........  8%  105M 7s
  4250K .......... .......... .......... .......... ..........  8%  116M 7s
  4300K .......... .......... .......... .......... ..........  9%  117M 7s
  4350K .......... .......... .......... .......... ..........  9%  115M 7s
  4400K .......... .......... .......... .......... ..........  9%  110M 7s
  4450K .......... .......... .......... .......... ..........  9%  150M 7s
  4500K .......... .......... .......... .......... ..........  9%  134M 7s
  4550K .......... .......... .......... .......... ..........  9%  144M 7s
  4600K .......... .......... .......... .......... ..........  9%  130M 6s
  4650K .......... .......... .......... .......... ..........  9%  117M 6s
  4700K .......... .......... .......... .......... ..........  9%  129M 6s
  4750K .......... .......... .......... .......... ..........  9%  134M 6s
  4800K .......... .......... .......... .......... .......... 10%  102M 6s
  4850K .......... .......... .......... .......... .......... 10%  138M 6s
  4900K .......... .......... .......... .......... .......... 10%  125M 6s
  4950K .......... .......... .......... .......... .......... 10%  138M 6s
  5000K .......... .......... .......... .......... .......... 10% 1.40M 6s
  5050K .......... .......... .......... .......... .......... 10%  100M 6s
  5100K .......... .......... .......... .......... .......... 10%  112M 6s
  5150K .......... .......... .......... .......... .......... 10% 96.8M 6s
  5200K .......... .......... .......... .......... .......... 10% 74.0M 6s
  5250K .......... .......... .......... .......... .......... 10%  141M 6s
  5300K .......... .......... .......... .......... .......... 11%  142M 6s
  5350K .......... .......... .......... .......... .......... 11%  115M 6s
  5400K .......... .......... .......... .......... .......... 11%  114M 6s
  5450K .......... .......... .......... .......... .......... 11%  119M 6s
  5500K .......... .......... .......... .......... .......... 11%  117M 6s
  5550K .......... .......... .......... .......... .......... 11%  139M 6s
  5600K .......... .......... .......... .......... .......... 11% 98.7M 6s
  5650K .......... .......... .......... .......... .......... 11%  119M 5s
  5700K .......... .......... .......... .......... .......... 11%  133M 5s
  5750K .......... .......... .......... .......... .......... 12%  135M 5s
  5800K .......... .......... .......... .......... .......... 12%  120M 5s
  5850K .......... .......... .......... .......... .......... 12%  118M 5s
  5900K .......... .......... .......... .......... .......... 12%  123M 5s
  5950K .......... .......... .......... .......... .......... 12%  126M 5s
  6000K .......... .......... .......... .......... .......... 12%  104M 5s
  6050K .......... .......... .......... .......... .......... 12% 1.47M 5s
  6100K .......... .......... .......... .......... .......... 12% 81.2M 5s
  6150K .......... .......... .......... .......... .......... 12% 85.1M 5s
  6200K .......... .......... .......... .......... .......... 12% 74.7M 5s
  6250K .......... .......... .......... .......... .......... 13% 99.0M 5s
  6300K .......... .......... .......... .......... .......... 13%  119M 5s
  6350K .......... .......... .......... .......... .......... 13%  114M 5s
  6400K .......... .......... .......... .......... .......... 13% 99.1M 5s
  6450K .......... .......... .......... .......... .......... 13%  127M 5s
  6500K .......... .......... .......... .......... .......... 13%  110M 5s
  6550K .......... .......... .......... .......... .......... 13%  107M 5s
  6600K .......... .......... .......... .......... .......... 13%  102M 5s
  6650K .......... .......... .......... .......... .......... 13%  107M 5s
  6700K .......... .......... .......... .......... .......... 13%  119M 5s
  6750K .......... .......... .......... .......... .......... 14%  114M 5s
  6800K .......... .......... .......... .......... .......... 14%  103M 5s
  6850K .......... .......... .......... .......... .......... 14%  135M 5s
  6900K .......... .......... .......... .......... .......... 14%  118M 5s
  6950K .......... .......... .......... .......... .......... 14%  126M 5s
  7000K .......... .......... .......... .......... .......... 14%  106M 5s
  7050K .......... .......... .......... .......... .......... 14%  106M 5s
  7100K .......... .......... .......... .......... .......... 14%  114M 4s
  7150K .......... .......... .......... .......... .......... 14%  120M 4s
  7200K .......... .......... .......... .......... .......... 15%  113M 4s
  7250K .......... .......... .......... .......... .......... 15%  118M 4s
  7300K .......... .......... .......... .......... .......... 15% 1.57M 5s
  7350K .......... .......... .......... .......... .......... 15% 86.8M 4s
  7400K .......... .......... .......... .......... .......... 15% 83.9M 4s
  7450K .......... .......... .......... .......... .......... 15% 79.9M 4s
  7500K .......... .......... .......... .......... .......... 15%  105M 4s
  7550K .......... .......... .......... .......... .......... 15%  116M 4s
  7600K .......... .......... .......... .......... .......... 15% 97.5M 4s
  7650K .......... .......... .......... .......... .......... 15%  109M 4s
  7700K .......... .......... .......... .......... .......... 16%  113M 4s
  7750K .......... .......... .......... .......... .......... 16%  117M 4s
  7800K .......... .......... .......... .......... .......... 16% 90.7M 4s
  7850K .......... .......... .......... .......... .......... 16%  102M 4s
  7900K .......... .......... .......... .......... .......... 16%  114M 4s
  7950K .......... .......... .......... .......... .......... 16%  115M 4s
  8000K .......... .......... .......... .......... .......... 16% 93.8M 4s
  8050K .......... .......... .......... .......... .......... 16%  109M 4s
  8100K .......... .......... .......... .......... .......... 16%  121M 4s
  8150K .......... .......... .......... .......... .......... 16% 1.05M 4s
  8200K .......... .......... .......... .......... .......... 17% 58.9M 4s
  8250K .......... .......... .......... .......... .......... 17% 74.1M 4s
  8300K .......... .......... .......... .......... .......... 17%  117M 4s
  8350K .......... .......... .......... .......... .......... 17%  126M 4s
  8400K .......... .......... .......... .......... .......... 17% 82.7M 4s
  8450K .......... .......... .......... .......... .......... 17%  109M 4s
  8500K .......... .......... .......... .......... .......... 17%  119M 4s
  8550K .......... .......... .......... .......... .......... 17%  122M 4s
  8600K .......... .......... .......... .......... .......... 17% 96.8M 4s
  8650K .......... .......... .......... .......... .......... 18%  111M 4s
  8700K .......... .......... .......... .......... .......... 18%  106M 4s
  8750K .......... .......... .......... .......... .......... 18%  122M 4s
  8800K .......... .......... .......... .......... .......... 18%  101M 4s
  8850K .......... .......... .......... .......... .......... 18%  116M 4s
  8900K .......... .......... .......... .......... .......... 18%  102M 4s
  8950K .......... .......... .......... .......... .......... 18%  106M 4s
  9000K .......... .......... .......... .......... .......... 18%  114M 4s
  9050K .......... .......... .......... .......... .......... 18%  117M 4s
  9100K .......... .......... .......... .......... .......... 18%  126M 4s
  9150K .......... .......... .......... .......... .......... 19%  128M 4s
  9200K .......... .......... .......... .......... .......... 19% 94.2M 4s
  9250K .......... .......... .......... .......... .......... 19%  128M 4s
  9300K .......... .......... .......... .......... .......... 19%  118M 4s
  9350K .......... .......... .......... .......... .......... 19%  117M 4s
  9400K .......... .......... .......... .......... .......... 19%  103M 4s
  9450K .......... .......... .......... .......... .......... 19%  115M 4s
  9500K .......... .......... .......... .......... .......... 19%  124M 4s
  9550K .......... .......... .......... .......... .......... 19%  117M 4s
  9600K .......... .......... .......... .......... .......... 19% 94.9M 4s
  9650K .......... .......... .......... .......... .......... 20%  123M 3s
  9700K .......... .......... .......... .......... .......... 20%  115M 3s
  9750K .......... .......... .......... .......... .......... 20% 1.73M 4s
  9800K .......... .......... .......... .......... .......... 20% 83.1M 4s
  9850K .......... .......... .......... .......... .......... 20% 99.3M 4s
  9900K .......... .......... .......... .......... .......... 20% 68.8M 3s
  9950K .......... .......... .......... .......... .......... 20%  103M 3s
 10000K .......... .......... .......... .......... .......... 20% 87.0M 3s
 10050K .......... .......... .......... .......... .......... 20%  117M 3s
 10100K .......... .......... .......... .......... .......... 21%  104M 3s
 10150K .......... .......... .......... .......... .......... 21%  122M 3s
 10200K .......... .......... .......... .......... .......... 21% 88.1M 3s
 10250K .......... .......... .......... .......... .......... 21%  109M 3s
 10300K .......... .......... .......... .......... .......... 21%  109M 3s
 10350K .......... .......... .......... .......... .......... 21%  101M 3s
 10400K .......... .......... .......... .......... .......... 21% 91.9M 3s
 10450K .......... .......... .......... .......... .......... 21%  109M 3s
 10500K .......... .......... .......... .......... .......... 21%  112M 3s
 10550K .......... .......... .......... .......... .......... 21%  106M 3s
 10600K .......... .......... .......... .......... .......... 22%  101M 3s
 10650K .......... .......... .......... .......... .......... 22%  105M 3s
 10700K .......... .......... .......... .......... .......... 22%  128M 3s
 10750K .......... .......... .......... .......... .......... 22%  125M 3s
 10800K .......... .......... .......... .......... .......... 22% 96.2M 3s
 10850K .......... .......... .......... .......... .......... 22%  118M 3s
 10900K .......... .......... .......... .......... .......... 22%  111M 3s
 10950K .......... .......... .......... .......... .......... 22%  141M 3s
 11000K .......... .......... .......... .......... .......... 22%  105M 3s
 11050K .......... .......... .......... .......... .......... 22%  127M 3s
 11100K .......... .......... .......... .......... .......... 23%  125M 3s
 11150K .......... .......... .......... .......... .......... 23%  118M 3s
 11200K .......... .......... .......... .......... .......... 23%  105M 3s
 11250K .......... .......... .......... .......... .......... 23%  124M 3s
 11300K .......... .......... .......... .......... .......... 23%  112M 3s
 11350K .......... .......... .......... .......... .......... 23%  135M 3s
 11400K .......... .......... .......... .......... .......... 23%  102M 3s
 11450K .......... .......... .......... .......... .......... 23% 1.84M 3s
 11500K .......... .......... .......... .......... .......... 23%  126M 3s
 11550K .......... .......... .......... .......... .......... 24%  135M 3s
 11600K .......... .......... .......... .......... .......... 24% 98.7M 3s
 11650K .......... .......... .......... .......... .......... 24%  145M 3s
 11700K .......... .......... .......... .......... .......... 24%  137M 3s
 11750K .......... .......... .......... .......... .......... 24%  134M 3s
 11800K .......... .......... .......... .......... .......... 24%  121M 3s
 11850K .......... .......... .......... .......... .......... 24%  126M 3s
 11900K .......... .......... .......... .......... .......... 24%  121M 3s
 11950K .......... .......... .......... .......... .......... 24%  132M 3s
 12000K .......... .......... .......... .......... .......... 24%  105M 3s
 12050K .......... .......... .......... .......... .......... 25%  128M 3s
 12100K .......... .......... .......... .......... .......... 25%  121M 3s
 12150K .......... .......... .......... .......... .......... 25%  121M 3s
 12200K .......... .......... .......... .......... .......... 25%  108M 3s
 12250K .......... .......... .......... .......... .......... 25% 1.03M 3s
 12300K .......... .......... .......... .......... .......... 25% 71.5M 3s
 12350K .......... .......... .......... .......... .......... 25% 91.8M 3s
 12400K .......... .......... .......... .......... .......... 25% 69.9M 3s
 12450K .......... .......... .......... .......... .......... 25% 71.3M 3s
 12500K .......... .......... .......... .......... .......... 25%  113M 3s
 12550K .......... .......... .......... .......... .......... 26%  121M 3s
 12600K .......... .......... .......... .......... .......... 26% 90.6M 3s
 12650K .......... .......... .......... .......... .......... 26%  112M 3s
 12700K .......... .......... .......... .......... .......... 26%  115M 3s
 12750K .......... .......... .......... .......... .......... 26%  106M 3s
 12800K .......... .......... .......... .......... .......... 26% 92.0M 3s
 12850K .......... .......... .......... .......... .......... 26%  124M 3s
 12900K .......... .......... .......... .......... .......... 26%  116M 3s
 12950K .......... .......... .......... .......... .......... 26%  106M 3s
 13000K .......... .......... .......... .......... .......... 27%  105M 3s
 13050K .......... .......... .......... .......... .......... 27%  108M 3s
 13100K .......... .......... .......... .......... .......... 27%  123M 3s
 13150K .......... .......... .......... .......... .......... 27%  121M 3s
 13200K .......... .......... .......... .......... .......... 27%  104M 3s
 13250K .......... .......... .......... .......... .......... 27%  121M 3s
 13300K .......... .......... .......... .......... .......... 27%  116M 3s
 13350K .......... .......... .......... .......... .......... 27%  123M 3s
 13400K .......... .......... .......... .......... .......... 27% 87.9M 3s
 13450K .......... .......... .......... .......... .......... 27%  102M 3s
 13500K .......... .......... .......... .......... .......... 28% 92.8M 3s
 13550K .......... .......... .......... .......... .......... 28%  123M 3s
 13600K .......... .......... .......... .......... .......... 28%  101M 3s
 13650K .......... .......... .......... .......... .......... 28%  111M 3s
 13700K .......... .......... .......... .......... .......... 28%  120M 3s
 13750K .......... .......... .......... .......... .......... 28%  103M 3s
 13800K .......... .......... .......... .......... .......... 28% 91.9M 3s
 13850K .......... .......... .......... .......... .......... 28%  102M 3s
 13900K .......... .......... .......... .......... .......... 28%  104M 3s
 13950K .......... .......... .......... .......... .......... 28%  114M 2s
 14000K .......... .......... .......... .......... .......... 29% 97.3M 2s
 14050K .......... .......... .......... .......... .......... 29%  118M 2s
 14100K .......... .......... .......... .......... .......... 29%  108M 2s
 14150K .......... .......... .......... .......... .......... 29%  115M 2s
 14200K .......... .......... .......... .......... .......... 29% 95.9M 2s
 14250K .......... .......... .......... .......... .......... 29% 2.08M 2s
 14300K .......... .......... .......... .......... .......... 29%  110M 2s
 14350K .......... .......... .......... .......... .......... 29% 92.2M 2s
 14400K .......... .......... .......... .......... .......... 29% 91.6M 2s
 14450K .......... .......... .......... .......... .......... 30% 79.6M 2s
 14500K .......... .......... .......... .......... .......... 30%  120M 2s
 14550K .......... .......... .......... .......... .......... 30%  121M 2s
 14600K .......... .......... .......... .......... .......... 30%  117M 2s
 14650K .......... .......... .......... .......... .......... 30%  135M 2s
 14700K .......... .......... .......... .......... .......... 30%  120M 2s
 14750K .......... .......... .......... .......... .......... 30%  119M 2s
 14800K .......... .......... .......... .......... .......... 30%  100M 2s
 14850K .......... .......... .......... .......... .......... 30%  126M 2s
 14900K .......... .......... .......... .......... .......... 30%  131M 2s
 14950K .......... .......... .......... .......... .......... 31%  126M 2s
 15000K .......... .......... .......... .......... .......... 31%  117M 2s
 15050K .......... .......... .......... .......... .......... 31%  135M 2s
 15100K .......... .......... .......... .......... .......... 31%  131M 2s
 15150K .......... .......... .......... .......... .......... 31%  135M 2s
 15200K .......... .......... .......... .......... .......... 31%  112M 2s
 15250K .......... .......... .......... .......... .......... 31%  129M 2s
 15300K .......... .......... .......... .......... .......... 31%  133M 2s
 15350K .......... .......... .......... .......... .......... 31%  127M 2s
 15400K .......... .......... .......... .......... .......... 31%  103M 2s
 15450K .......... .......... .......... .......... .......... 32%  120M 2s
 15500K .......... .......... .......... .......... .......... 32%  133M 2s
 15550K .......... .......... .......... .......... .......... 32%  119M 2s
 15600K .......... .......... .......... .......... .......... 32%  109M 2s
 15650K .......... .......... .......... .......... .......... 32%  132M 2s
 15700K .......... .......... .......... .......... .......... 32%  134M 2s
 15750K .......... .......... .......... .......... .......... 32%  132M 2s
 15800K .......... .......... .......... .......... .......... 32%  109M 2s
 15850K .......... .......... .......... .......... .......... 32%  128M 2s
 15900K .......... .......... .......... .......... .......... 33%  133M 2s
 15950K .......... .......... .......... .......... .......... 33%  135M 2s
 16000K .......... .......... .......... .......... .......... 33%  116M 2s
 16050K .......... .......... .......... .......... .......... 33% 1.78M 2s
 16100K .......... .......... .......... .......... .......... 33% 92.7M 2s
 16150K .......... .......... .......... .......... .......... 33%  126M 2s
 16200K .......... .......... .......... .......... .......... 33%  104M 2s
 16250K .......... .......... .......... .......... .......... 33%  128M 2s
 16300K .......... .......... .......... .......... .......... 33%  131M 2s
 16350K .......... .......... .......... .......... .......... 33%  989K 2s
 16400K .......... .......... .......... .......... .......... 34% 82.1M 2s
 16450K .......... .......... .......... .......... .......... 34%  106M 2s
 16500K .......... .......... .......... .......... .......... 34% 98.0M 2s
 16550K .......... .......... .......... .......... .......... 34%  116M 2s
 16600K .......... .......... .......... .......... .......... 34% 94.7M 2s
 16650K .......... .......... .......... .......... .......... 34%  115M 2s
 16700K .......... .......... .......... .......... .......... 34%  126M 2s
 16750K .......... .......... .......... .......... .......... 34%  123M 2s
 16800K .......... .......... .......... .......... .......... 34%  114M 2s
 16850K .......... .......... .......... .......... .......... 34%  118M 2s
 16900K .......... .......... .......... .......... .......... 35%  122M 2s
 16950K .......... .......... .......... .......... .......... 35%  128M 2s
 17000K .......... .......... .......... .......... .......... 35%  103M 2s
 17050K .......... .......... .......... .......... .......... 35%  125M 2s
 17100K .......... .......... .......... .......... .......... 35%  124M 2s
 17150K .......... .......... .......... .......... .......... 35%  111M 2s
 17200K .......... .......... .......... .......... .......... 35%  104M 2s
 17250K .......... .......... .......... .......... .......... 35%  111M 2s
 17300K .......... .......... .......... .......... .......... 35%  123M 2s
 17350K .......... .......... .......... .......... .......... 36%  117M 2s
 17400K .......... .......... .......... .......... .......... 36%  111M 2s
 17450K .......... .......... .......... .......... .......... 36%  129M 2s
 17500K .......... .......... .......... .......... .......... 36%  123M 2s
 17550K .......... .......... .......... .......... .......... 36%  132M 2s
 17600K .......... .......... .......... .......... .......... 36%  105M 2s
 17650K .......... .......... .......... .......... .......... 36%  107M 2s
 17700K .......... .......... .......... .......... .......... 36%  129M 2s
 17750K .......... .......... .......... .......... .......... 36%  115M 2s
 17800K .......... .......... .......... .......... .......... 36%  117M 2s
 17850K .......... .......... .......... .......... .......... 37%  134M 2s
 17900K .......... .......... .......... .......... .......... 37%  126M 2s
 17950K .......... .......... .......... .......... .......... 37%  128M 2s
 18000K .......... .......... .......... .......... .......... 37%  109M 2s
 18050K .......... .......... .......... .......... .......... 37%  123M 2s
 18100K .......... .......... .......... .......... .......... 37%  132M 2s
 18150K .......... .......... .......... .......... .......... 37%  110M 2s
 18200K .......... .......... .......... .......... .......... 37%  106M 2s
 18250K .......... .......... .......... .......... .......... 37%  124M 2s
 18300K .......... .......... .......... .......... .......... 37%  135M 2s
 18350K .......... .......... .......... .......... .......... 38%  132M 2s
 18400K .......... .......... .......... .......... .......... 38%  105M 2s
 18450K .......... .......... .......... .......... .......... 38%  120M 2s
 18500K .......... .......... .......... .......... .......... 38%  123M 2s
 18550K .......... .......... .......... .......... .......... 38%  120M 2s
 18600K .......... .......... .......... .......... .......... 38%  104M 2s
 18650K .......... .......... .......... .......... .......... 38%  108M 2s
 18700K .......... .......... .......... .......... .......... 38%  118M 2s
 18750K .......... .......... .......... .......... .......... 38% 2.20M 2s
 18800K .......... .......... .......... .......... .......... 39% 25.5M 2s
 18850K .......... .......... .......... .......... .......... 39% 60.8M 2s
 18900K .......... .......... .......... .......... .......... 39%  109M 2s
 18950K .......... .......... .......... .......... .......... 39%  102M 2s
 19000K .......... .......... .......... .......... .......... 39% 62.2M 2s
 19050K .......... .......... .......... .......... .......... 39% 93.9M 2s
 19100K .......... .......... .......... .......... .......... 39%  125M 2s
 19150K .......... .......... .......... .......... .......... 39%  120M 2s
 19200K .......... .......... .......... .......... .......... 39% 98.1M 2s
 19250K .......... .......... .......... .......... .......... 39%  127M 2s
 19300K .......... .......... .......... .......... .......... 40%  110M 2s
 19350K .......... .......... .......... .......... .......... 40%  135M 2s
 19400K .......... .......... .......... .......... .......... 40%  107M 2s
 19450K .......... .......... .......... .......... .......... 40%  112M 2s
 19500K .......... .......... .......... .......... .......... 40%  128M 2s
 19550K .......... .......... .......... .......... .......... 40%  116M 2s
 19600K .......... .......... .......... .......... .......... 40%  101M 2s
 19650K .......... .......... .......... .......... .......... 40%  127M 2s
 19700K .......... .......... .......... .......... .......... 40%  116M 2s
 19750K .......... .......... .......... .......... .......... 40%  148M 2s
 19800K .......... .......... .......... .......... .......... 41%  113M 2s
 19850K .......... .......... .......... .......... .......... 41%  117M 2s
 19900K .......... .......... .......... .......... .......... 41%  132M 2s
 19950K .......... .......... .......... .......... .......... 41%  121M 2s
 20000K .......... .......... .......... .......... .......... 41%  108M 2s
 20050K .......... .......... .......... .......... .......... 41%  126M 2s
 20100K .......... .......... .......... .......... .......... 41%  102M 2s
 20150K .......... .......... .......... .......... .......... 41%  128M 2s
 20200K .......... .......... .......... .......... .......... 41%  103M 2s
 20250K .......... .......... .......... .......... .......... 42%  127M 2s
 20300K .......... .......... .......... .......... .......... 42%  127M 2s
 20350K .......... .......... .......... .......... .......... 42% 1.84M 2s
 20400K .......... .......... .......... .......... .......... 42% 88.3M 2s
 20450K .......... .......... .......... .......... .......... 42%  945K 2s
 20500K .......... .......... .......... .......... .......... 42%  107M 2s
 20550K .......... .......... .......... .......... .......... 42% 98.0M 2s
 20600K .......... .......... .......... .......... .......... 42% 91.3M 2s
 20650K .......... .......... .......... .......... .......... 42% 92.3M 2s
 20700K .......... .......... .......... .......... .......... 42% 90.8M 2s
 20750K .......... .......... .......... .......... .......... 43% 92.0M 2s
 20800K .......... .......... .......... .......... .......... 43%  100M 2s
 20850K .......... .......... .......... .......... .......... 43%  123M 2s
 20900K .......... .......... .......... .......... .......... 43%  123M 2s
 20950K .......... .......... .......... .......... .......... 43%  130M 2s
 21000K .......... .......... .......... .......... .......... 43%  102M 2s
 21050K .......... .......... .......... .......... .......... 43%  127M 2s
 21100K .......... .......... .......... .......... .......... 43%  107M 2s
 21150K .......... .......... .......... .......... .......... 43%  124M 2s
 21200K .......... .......... .......... .......... .......... 44%  104M 2s
 21250K .......... .......... .......... .......... .......... 44%  115M 2s
 21300K .......... .......... .......... .......... .......... 44%  123M 2s
 21350K .......... .......... .......... .......... .......... 44%  120M 2s
 21400K .......... .......... .......... .......... .......... 44%  101M 2s
 21450K .......... .......... .......... .......... .......... 44%  121M 2s
 21500K .......... .......... .......... .......... .......... 44%  129M 2s
 21550K .......... .......... .......... .......... .......... 44%  121M 2s
 21600K .......... .......... .......... .......... .......... 44% 99.8M 2s
 21650K .......... .......... .......... .......... .......... 44%  121M 2s
 21700K .......... .......... .......... .......... .......... 45%  114M 2s
 21750K .......... .......... .......... .......... .......... 45%  116M 2s
 21800K .......... .......... .......... .......... .......... 45% 98.3M 2s
 21850K .......... .......... .......... .......... .......... 45%  117M 2s
 21900K .......... .......... .......... .......... .......... 45%  109M 2s
 21950K .......... .......... .......... .......... .......... 45%  110M 2s
 22000K .......... .......... .......... .......... .......... 45% 98.4M 2s
 22050K .......... .......... .......... .......... .......... 45%  130M 2s
 22100K .......... .......... .......... .......... .......... 45%  110M 2s
 22150K .......... .......... .......... .......... .......... 45%  122M 2s
 22200K .......... .......... .......... .......... .......... 46%  104M 2s
 22250K .......... .......... .......... .......... .......... 46%  113M 2s
 22300K .......... .......... .......... .......... .......... 46%  116M 1s
 22350K .......... .......... .......... .......... .......... 46%  110M 1s
 22400K .......... .......... .......... .......... .......... 46%  104M 1s
 22450K .......... .......... .......... .......... .......... 46%  103M 1s
 22500K .......... .......... .......... .......... .......... 46%  118M 1s
 22550K .......... .......... .......... .......... .......... 46%  117M 1s
 22600K .......... .......... .......... .......... .......... 46%  101M 1s
 22650K .......... .......... .......... .......... .......... 47%  113M 1s
 22700K .......... .......... .......... .......... .......... 47%  112M 1s
 22750K .......... .......... .......... .......... .......... 47%  125M 1s
 22800K .......... .......... .......... .......... .......... 47% 96.7M 1s
 22850K .......... .......... .......... .......... .......... 47%  113M 1s
 22900K .......... .......... .......... .......... .......... 47%  120M 1s
 22950K .......... .......... .......... .......... .......... 47%  114M 1s
 23000K .......... .......... .......... .......... .......... 47% 99.6M 1s
 23050K .......... .......... .......... .......... .......... 47% 93.1M 1s
 23100K .......... .......... .......... .......... .......... 47%  104M 1s
 23150K .......... .......... .......... .......... .......... 48%  119M 1s
 23200K .......... .......... .......... .......... .......... 48% 2.72M 1s
 23250K .......... .......... .......... .......... .......... 48%  111M 1s
 23300K .......... .......... .......... .......... .......... 48%  113M 1s
 23350K .......... .......... .......... .......... .......... 48% 91.3M 1s
 23400K .......... .......... .......... .......... .......... 48% 92.5M 1s
 23450K .......... .......... .......... .......... .......... 48% 89.6M 1s
 23500K .......... .......... .......... .......... .......... 48%  106M 1s
 23550K .......... .......... .......... .......... .......... 48% 99.2M 1s
 23600K .......... .......... .......... .......... .......... 48% 93.4M 1s
 23650K .......... .......... .......... .......... .......... 49%  110M 1s
 23700K .......... .......... .......... .......... .......... 49%  101M 1s
 23750K .......... .......... .......... .......... .......... 49% 97.4M 1s
 23800K .......... .......... .......... .......... .......... 49% 99.9M 1s
 23850K .......... .......... .......... .......... .......... 49%  124M 1s
 23900K .......... .......... .......... .......... .......... 49%  111M 1s
 23950K .......... .......... .......... .......... .......... 49%  122M 1s
 24000K .......... .......... .......... .......... .......... 49% 86.3M 1s
 24050K .......... .......... .......... .......... .......... 49%  118M 1s
 24100K .......... .......... .......... .......... .......... 50%  109M 1s
 24150K .......... .......... .......... .......... .......... 50%  107M 1s
 24200K .......... .......... .......... .......... .......... 50%  101M 1s
 24250K .......... .......... .......... .......... .......... 50%  107M 1s
 24300K .......... .......... .......... .......... .......... 50%  128M 1s
 24350K .......... .......... .......... .......... .......... 50%  114M 1s
 24400K .......... .......... .......... .......... .......... 50% 93.4M 1s
 24450K .......... .......... .......... .......... .......... 50%  110M 1s
 24500K .......... .......... .......... .......... .......... 50%  121M 1s
 24550K .......... .......... .......... .......... .......... 50% 1.09M 1s
 24600K .......... .......... .......... .......... .......... 51% 93.3M 1s
 24650K .......... .......... .......... .......... .......... 51%  112M 1s
 24700K .......... .......... .......... .......... .......... 51%  121M 1s
 24750K .......... .......... .......... .......... .......... 51%  117M 1s
 24800K .......... .......... .......... .......... .......... 51% 94.4M 1s
 24850K .......... .......... .......... .......... .......... 51%  104M 1s
 24900K .......... .......... .......... .......... .......... 51%  121M 1s
 24950K .......... .......... .......... .......... .......... 51%  115M 1s
 25000K .......... .......... .......... .......... .......... 51%  108M 1s
 25050K .......... .......... .......... .......... .......... 51%  135M 1s
 25100K .......... .......... .......... .......... .......... 52%  132M 1s
 25150K .......... .......... .......... .......... .......... 52%  116M 1s
 25200K .......... .......... .......... .......... .......... 52% 99.9M 1s
 25250K .......... .......... .......... .......... .......... 52%  120M 1s
 25300K .......... .......... .......... .......... .......... 52%  131M 1s
 25350K .......... .......... .......... .......... .......... 52%  119M 1s
 25400K .......... .......... .......... .......... .......... 52% 96.3M 1s
 25450K .......... .......... .......... .......... .......... 52%  119M 1s
 25500K .......... .......... .......... .......... .......... 52%  114M 1s
 25550K .......... .......... .......... .......... .......... 53%  118M 1s
 25600K .......... .......... .......... .......... .......... 53%  100M 1s
 25650K .......... .......... .......... .......... .......... 53%  132M 1s
 25700K .......... .......... .......... .......... .......... 53%  112M 1s
 25750K .......... .......... .......... .......... .......... 53%  118M 1s
 25800K .......... .......... .......... .......... .......... 53%  106M 1s
 25850K .......... .......... .......... .......... .......... 53%  102M 1s
 25900K .......... .......... .......... .......... .......... 53%  122M 1s
 25950K .......... .......... .......... .......... .......... 53%  115M 1s
 26000K .......... .......... .......... .......... .......... 53%  103M 1s
 26050K .......... .......... .......... .......... .......... 54%  125M 1s
 26100K .......... .......... .......... .......... .......... 54%  126M 1s
 26150K .......... .......... .......... .......... .......... 54%  127M 1s
 26200K .......... .......... .......... .......... .......... 54%  100M 1s
 26250K .......... .......... .......... .......... .......... 54%  112M 1s
 26300K .......... .......... .......... .......... .......... 54%  109M 1s
 26350K .......... .......... .......... .......... .......... 54%  111M 1s
 26400K .......... .......... .......... .......... .......... 54%  102M 1s
 26450K .......... .......... .......... .......... .......... 54%  112M 1s
 26500K .......... .......... .......... .......... .......... 54%  112M 1s
 26550K .......... .......... .......... .......... .......... 55%  109M 1s
 26600K .......... .......... .......... .......... .......... 55% 94.7M 1s
 26650K .......... .......... .......... .......... .......... 55%  119M 1s
 26700K .......... .......... .......... .......... .......... 55%  116M 1s
 26750K .......... .......... .......... .......... .......... 55%  119M 1s
 26800K .......... .......... .......... .......... .......... 55% 99.5M 1s
 26850K .......... .......... .......... .......... .......... 55%  112M 1s
 26900K .......... .......... .......... .......... .......... 55% 2.22M 1s
 26950K .......... .......... .......... .......... .......... 55% 72.6M 1s
 27000K .......... .......... .......... .......... .......... 56% 74.7M 1s
 27050K .......... .......... .......... .......... .......... 56%  106M 1s
 27100K .......... .......... .......... .......... .......... 56% 82.2M 1s
 27150K .......... .......... .......... .......... .......... 56%  114M 1s
 27200K .......... .......... .......... .......... .......... 56% 95.9M 1s
 27250K .......... .......... .......... .......... .......... 56%  105M 1s
 27300K .......... .......... .......... .......... .......... 56%  107M 1s
 27350K .......... .......... .......... .......... .......... 56%  116M 1s
 27400K .......... .......... .......... .......... .......... 56% 94.4M 1s
 27450K .......... .......... .......... .......... .......... 56%  124M 1s
 27500K .......... .......... .......... .......... .......... 57%  125M 1s
 27550K .......... .......... .......... .......... .......... 57%  100M 1s
 27600K .......... .......... .......... .......... .......... 57% 99.2M 1s
 27650K .......... .......... .......... .......... .......... 57%  115M 1s
 27700K .......... .......... .......... .......... .......... 57%  111M 1s
 27750K .......... .......... .......... .......... .......... 57%  112M 1s
 27800K .......... .......... .......... .......... .......... 57% 96.2M 1s
 27850K .......... .......... .......... .......... .......... 57%  107M 1s
 27900K .......... .......... .......... .......... .......... 57%  107M 1s
 27950K .......... .......... .......... .......... .......... 57%  118M 1s
 28000K .......... .......... .......... .......... .......... 58% 89.6M 1s
 28050K .......... .......... .......... .......... .......... 58%  108M 1s
 28100K .......... .......... .......... .......... .......... 58%  128M 1s
 28150K .......... .......... .......... .......... .......... 58% 98.5M 1s
 28200K .......... .......... .......... .......... .......... 58% 94.9M 1s
 28250K .......... .......... .......... .......... .......... 58%  120M 1s
 28300K .......... .......... .......... .......... .......... 58%  105M 1s
 28350K .......... .......... .......... .......... .......... 58%  114M 1s
 28400K .......... .......... .......... .......... .......... 58% 97.8M 1s
 28450K .......... .......... .......... .......... .......... 59%  125M 1s
 28500K .......... .......... .......... .......... .......... 59%  117M 1s
 28550K .......... .......... .......... .......... .......... 59% 1.83M 1s
 28600K .......... .......... .......... .......... .......... 59% 94.2M 1s
 28650K .......... .......... .......... .......... .......... 59%  973K 1s
 28700K .......... .......... .......... .......... .......... 59% 81.8M 1s
 28750K .......... .......... .......... .......... .......... 59%  120M 1s
 28800K .......... .......... .......... .......... .......... 59% 90.3M 1s
 28850K .......... .......... .......... .......... .......... 59%  112M 1s
 28900K .......... .......... .......... .......... .......... 59%  102M 1s
 28950K .......... .......... .......... .......... .......... 60%  102M 1s
 29000K .......... .......... .......... .......... .......... 60% 90.6M 1s
 29050K .......... .......... .......... .......... .......... 60%  103M 1s
 29100K .......... .......... .......... .......... .......... 60%  116M 1s
 29150K .......... .......... .......... .......... .......... 60%  110M 1s
 29200K .......... .......... .......... .......... .......... 60% 96.9M 1s
 29250K .......... .......... .......... .......... .......... 60%  109M 1s
 29300K .......... .......... .......... .......... .......... 60%  126M 1s
 29350K .......... .......... .......... .......... .......... 60%  141M 1s
 29400K .......... .......... .......... .......... .......... 60%  114M 1s
 29450K .......... .......... .......... .......... .......... 61%  141M 1s
 29500K .......... .......... .......... .......... .......... 61%  133M 1s
 29550K .......... .......... .......... .......... .......... 61%  114M 1s
 29600K .......... .......... .......... .......... .......... 61%  115M 1s
 29650K .......... .......... .......... .......... .......... 61%  123M 1s
 29700K .......... .......... .......... .......... .......... 61%  121M 1s
 29750K .......... .......... .......... .......... .......... 61%  123M 1s
 29800K .......... .......... .......... .......... .......... 61%  113M 1s
 29850K .......... .......... .......... .......... .......... 61%  120M 1s
 29900K .......... .......... .......... .......... .......... 62%  128M 1s
 29950K .......... .......... .......... .......... .......... 62%  111M 1s
 30000K .......... .......... .......... .......... .......... 62%  112M 1s
 30050K .......... .......... .......... .......... .......... 62%  124M 1s
 30100K .......... .......... .......... .......... .......... 62%  129M 1s
 30150K .......... .......... .......... .......... .......... 62%  133M 1s
 30200K .......... .......... .......... .......... .......... 62%  113M 1s
 30250K .......... .......... .......... .......... .......... 62%  135M 1s
 30300K .......... .......... .......... .......... .......... 62%  131M 1s
 30350K .......... .......... .......... .......... .......... 62%  137M 1s
 30400K .......... .......... .......... .......... .......... 63%  115M 1s
 30450K .......... .......... .......... .......... .......... 63%  126M 1s
 30500K .......... .......... .......... .......... .......... 63%  121M 1s
 30550K .......... .......... .......... .......... .......... 63%  127M 1s
 30600K .......... .......... .......... .......... .......... 63%  112M 1s
 30650K .......... .......... .......... .......... .......... 63%  108M 1s
 30700K .......... .......... .......... .......... .......... 63%  112M 1s
 30750K .......... .......... .......... .......... .......... 63%  112M 1s
 30800K .......... .......... .......... .......... .......... 63% 89.6M 1s
 30850K .......... .......... .......... .......... .......... 63%  119M 1s
 30900K .......... .......... .......... .......... .......... 64%  129M 1s
 30950K .......... .......... .......... .......... .......... 64%  119M 1s
 31000K .......... .......... .......... .......... .......... 64% 99.0M 1s
 31050K .......... .......... .......... .......... .......... 64%  124M 1s
 31100K .......... .......... .......... .......... .......... 64%  124M 1s
 31150K .......... .......... .......... .......... .......... 64%  122M 1s
 31200K .......... .......... .......... .......... .......... 64%  102M 1s
 31250K .......... .......... .......... .......... .......... 64%  121M 1s
 31300K .......... .......... .......... .......... .......... 64%  118M 1s
 31350K .......... .......... .......... .......... .......... 65%  119M 1s
 31400K .......... .......... .......... .......... .......... 65% 99.3M 1s
 31450K .......... .......... .......... .......... .......... 65%  124M 1s
 31500K .......... .......... .......... .......... .......... 65%  109M 1s
 31550K .......... .......... .......... .......... .......... 65%  115M 1s
 31600K .......... .......... .......... .......... .......... 65% 87.6M 1s
 31650K .......... .......... .......... .......... .......... 65% 2.94M 1s
 31700K .......... .......... .......... .......... .......... 65% 98.1M 1s
 31750K .......... .......... .......... .......... .......... 65% 97.8M 1s
 31800K .......... .......... .......... .......... .......... 65% 78.4M 1s
 31850K .......... .......... .......... .......... .......... 66% 86.1M 1s
 31900K .......... .......... .......... .......... .......... 66% 95.0M 1s
 31950K .......... .......... .......... .......... .......... 66%  102M 1s
 32000K .......... .......... .......... .......... .......... 66%  104M 1s
 32050K .......... .......... .......... .......... .......... 66%  122M 1s
 32100K .......... .......... .......... .......... .......... 66%  106M 1s
 32150K .......... .......... .......... .......... .......... 66% 92.7M 1s
 32200K .......... .......... .......... .......... .......... 66% 95.8M 1s
 32250K .......... .......... .......... .......... .......... 66%  109M 1s
 32300K .......... .......... .......... .......... .......... 66%  109M 1s
 32350K .......... .......... .......... .......... .......... 67%  112M 1s
 32400K .......... .......... .......... .......... .......... 67% 99.9M 1s
 32450K .......... .......... .......... .......... .......... 67%  124M 1s
 32500K .......... .......... .......... .......... .......... 67%  121M 1s
 32550K .......... .......... .......... .......... .......... 67%  118M 1s
 32600K .......... .......... .......... .......... .......... 67%  112M 1s
 32650K .......... .......... .......... .......... .......... 67%  109M 1s
 32700K .......... .......... .......... .......... .......... 67%  108M 1s
 32750K .......... .......... .......... .......... .......... 67% 1.09M 1s
 32800K .......... .......... .......... .......... .......... 68% 89.9M 1s
 32850K .......... .......... .......... .......... .......... 68%  105M 1s
 32900K .......... .......... .......... .......... .......... 68% 92.8M 1s
 32950K .......... .......... .......... .......... .......... 68% 83.3M 1s
 33000K .......... .......... .......... .......... .......... 68% 80.5M 1s
 33050K .......... .......... .......... .......... .......... 68%  112M 1s
 33100K .......... .......... .......... .......... .......... 68%  116M 1s
 33150K .......... .......... .......... .......... .......... 68%  108M 1s
 33200K .......... .......... .......... .......... .......... 68% 88.5M 1s
 33250K .......... .......... .......... .......... .......... 68%  108M 1s
 33300K .......... .......... .......... .......... .......... 69%  112M 1s
 33350K .......... .......... .......... .......... .......... 69%  109M 1s
 33400K .......... .......... .......... .......... .......... 69% 95.1M 1s
 33450K .......... .......... .......... .......... .......... 69%  107M 1s
 33500K .......... .......... .......... .......... .......... 69%  105M 1s
 33550K .......... .......... .......... .......... .......... 69%  104M 1s
 33600K .......... .......... .......... .......... .......... 69% 82.1M 1s
 33650K .......... .......... .......... .......... .......... 69%  101M 1s
 33700K .......... .......... .......... .......... .......... 69%  105M 1s
 33750K .......... .......... .......... .......... .......... 69% 77.6M 1s
 33800K .......... .......... .......... .......... .......... 70% 77.0M 1s
 33850K .......... .......... .......... .......... .......... 70%  102M 1s
 33900K .......... .......... .......... .......... .......... 70%  102M 1s
 33950K .......... .......... .......... .......... .......... 70%  100M 1s
 34000K .......... .......... .......... .......... .......... 70% 86.5M 1s
 34050K .......... .......... .......... .......... .......... 70%  104M 1s
 34100K .......... .......... .......... .......... .......... 70% 95.3M 1s
 34150K .......... .......... .......... .......... .......... 70%  105M 1s
 34200K .......... .......... .......... .......... .......... 70% 78.0M 1s
 34250K .......... .......... .......... .......... .......... 71%  111M 1s
 34300K .......... .......... .......... .......... .......... 71%  103M 1s
 34350K .......... .......... .......... .......... .......... 71% 90.3M 1s
 34400K .......... .......... .......... .......... .......... 71% 85.4M 1s
 34450K .......... .......... .......... .......... .......... 71% 97.6M 1s
 34500K .......... .......... .......... .......... .......... 71%  101M 1s
 34550K .......... .......... .......... .......... .......... 71% 96.7M 1s
 34600K .......... .......... .......... .......... .......... 71% 79.5M 1s
 34650K .......... .......... .......... .......... .......... 71%  103M 1s
 34700K .......... .......... .......... .......... .......... 71%  102M 1s
 34750K .......... .......... .......... .......... .......... 72%  106M 1s
 34800K .......... .......... .......... .......... .......... 72% 84.2M 1s
 34850K .......... .......... .......... .......... .......... 72% 99.5M 1s
 34900K .......... .......... .......... .......... .......... 72%  111M 1s
 34950K .......... .......... .......... .......... .......... 72%  108M 1s
 35000K .......... .......... .......... .......... .......... 72%  108M 1s
 35050K .......... .......... .......... .......... .......... 72% 97.4M 1s
 35100K .......... .......... .......... .......... .......... 72%  108M 1s
 35150K .......... .......... .......... .......... .......... 72%  109M 1s
 35200K .......... .......... .......... .......... .......... 72% 92.4M 1s
 35250K .......... .......... .......... .......... .......... 73% 2.78M 1s
 35300K .......... .......... .......... .......... .......... 73% 90.6M 1s
 35350K .......... .......... .......... .......... .......... 73% 94.5M 1s
 35400K .......... .......... .......... .......... .......... 73% 82.0M 1s
 35450K .......... .......... .......... .......... .......... 73%  102M 1s
 35500K .......... .......... .......... .......... .......... 73%  116M 1s
 35550K .......... .......... .......... .......... .......... 73%  109M 1s
 35600K .......... .......... .......... .......... .......... 73% 87.1M 1s
 35650K .......... .......... .......... .......... .......... 73%  102M 1s
 35700K .......... .......... .......... .......... .......... 74%  101M 1s
 35750K .......... .......... .......... .......... .......... 74%  120M 1s
 35800K .......... .......... .......... .......... .......... 74%  102M 1s
 35850K .......... .......... .......... .......... .......... 74%  116M 1s
 35900K .......... .......... .......... .......... .......... 74% 98.1M 1s
 35950K .......... .......... .......... .......... .......... 74% 93.0M 1s
 36000K .......... .......... .......... .......... .......... 74% 82.1M 1s
 36050K .......... .......... .......... .......... .......... 74% 96.8M 1s
 36100K .......... .......... .......... .......... .......... 74%  103M 1s
 36150K .......... .......... .......... .......... .......... 74%  103M 1s
 36200K .......... .......... .......... .......... .......... 75% 89.4M 1s
 36250K .......... .......... .......... .......... .......... 75% 97.1M 1s
 36300K .......... .......... .......... .......... .......... 75%  101M 1s
 36350K .......... .......... .......... .......... .......... 75%  108M 1s
 36400K .......... .......... .......... .......... .......... 75% 81.2M 1s
 36450K .......... .......... .......... .......... .......... 75%  101M 1s
 36500K .......... .......... .......... .......... .......... 75% 97.1M 1s
 36550K .......... .......... .......... .......... .......... 75%  102M 1s
 36600K .......... .......... .......... .......... .......... 75% 90.0M 1s
 36650K .......... .......... .......... .......... .......... 75%  103M 1s
 36700K .......... .......... .......... .......... .......... 76%  103M 1s
 36750K .......... .......... .......... .......... .......... 76%  106M 1s
 36800K .......... .......... .......... .......... .......... 76% 1.79M 1s
 36850K .......... .......... .......... .......... .......... 76%  880K 1s
 36900K .......... .......... .......... .......... .......... 76% 90.4M 1s
 36950K .......... .......... .......... .......... .......... 76% 98.5M 1s
 37000K .......... .......... .......... .......... .......... 76% 72.6M 1s
 37050K .......... .......... .......... .......... .......... 76% 89.4M 1s
 37100K .......... .......... .......... .......... .......... 76% 92.9M 1s
 37150K .......... .......... .......... .......... .......... 77% 84.1M 1s
 37200K .......... .......... .......... .......... .......... 77% 81.3M 1s
 37250K .......... .......... .......... .......... .......... 77% 99.9M 1s
 37300K .......... .......... .......... .......... .......... 77% 95.1M 1s
 37350K .......... .......... .......... .......... .......... 77% 94.4M 1s
 37400K .......... .......... .......... .......... .......... 77% 88.0M 1s
 37450K .......... .......... .......... .......... .......... 77%  101M 1s
 37500K .......... .......... .......... .......... .......... 77%  111M 1s
 37550K .......... .......... .......... .......... .......... 77%  101M 0s
 37600K .......... .......... .......... .......... .......... 77% 81.5M 0s
 37650K .......... .......... .......... .......... .......... 78% 96.4M 0s
 37700K .......... .......... .......... .......... .......... 78%  100M 0s
 37750K .......... .......... .......... .......... .......... 78%  119M 0s
 37800K .......... .......... .......... .......... .......... 78% 89.8M 0s
 37850K .......... .......... .......... .......... .......... 78% 92.6M 0s
 37900K .......... .......... .......... .......... .......... 78%  102M 0s
 37950K .......... .......... .......... .......... .......... 78% 97.6M 0s
 38000K .......... .......... .......... .......... .......... 78% 84.6M 0s
 38050K .......... .......... .......... .......... .......... 78%  114M 0s
 38100K .......... .......... .......... .......... .......... 78%  116M 0s
 38150K .......... .......... .......... .......... .......... 79%  108M 0s
 38200K .......... .......... .......... .......... .......... 79% 79.6M 0s
 38250K .......... .......... .......... .......... .......... 79% 97.9M 0s
 38300K .......... .......... .......... .......... .......... 79% 93.6M 0s
 38350K .......... .......... .......... .......... .......... 79% 99.7M 0s
 38400K .......... .......... .......... .......... .......... 79% 92.0M 0s
 38450K .......... .......... .......... .......... .......... 79% 91.5M 0s
 38500K .......... .......... .......... .......... .......... 79%  115M 0s
 38550K .......... .......... .......... .......... .......... 79%  103M 0s
 38600K .......... .......... .......... .......... .......... 80% 97.2M 0s
 38650K .......... .......... .......... .......... .......... 80%  101M 0s
 38700K .......... .......... .......... .......... .......... 80%  122M 0s
 38750K .......... .......... .......... .......... .......... 80%  114M 0s
 38800K .......... .......... .......... .......... .......... 80% 92.4M 0s
 38850K .......... .......... .......... .......... .......... 80%  111M 0s
 38900K .......... .......... .......... .......... .......... 80%  118M 0s
 38950K .......... .......... .......... .......... .......... 80%  122M 0s
 39000K .......... .......... .......... .......... .......... 80% 93.8M 0s
 39050K .......... .......... .......... .......... .......... 80%  108M 0s
 39100K .......... .......... .......... .......... .......... 81%  111M 0s
 39150K .......... .......... .......... .......... .......... 81%  101M 0s
 39200K .......... .......... .......... .......... .......... 81% 85.1M 0s
 39250K .......... .......... .......... .......... .......... 81%  103M 0s
 39300K .......... .......... .......... .......... .......... 81%  116M 0s
 39350K .......... .......... .......... .......... .......... 81%  110M 0s
 39400K .......... .......... .......... .......... .......... 81% 99.0M 0s
 39450K .......... .......... .......... .......... .......... 81% 97.0M 0s
 39500K .......... .......... .......... .......... .......... 81%  110M 0s
 39550K .......... .......... .......... .......... .......... 81%  102M 0s
 39600K .......... .......... .......... .......... .......... 82% 95.3M 0s
 39650K .......... .......... .......... .......... .......... 82%  113M 0s
 39700K .......... .......... .......... .......... .......... 82%  101M 0s
 39750K .......... .......... .......... .......... .......... 82%  106M 0s
 39800K .......... .......... .......... .......... .......... 82% 99.3M 0s
 39850K .......... .......... .......... .......... .......... 82%  100M 0s
 39900K .......... .......... .......... .......... .......... 82% 2.87M 0s
 39950K .......... .......... .......... .......... .......... 82% 76.1M 0s
 40000K .......... .......... .......... .......... .......... 82% 61.1M 0s
 40050K .......... .......... .......... .......... .......... 83% 96.5M 0s
 40100K .......... .......... .......... .......... .......... 83%  124M 0s
 40150K .......... .......... .......... .......... .......... 83%  103M 0s
 40200K .......... .......... .......... .......... .......... 83% 99.4M 0s
 40250K .......... .......... .......... .......... .......... 83%  109M 0s
 40300K .......... .......... .......... .......... .......... 83%  117M 0s
 40350K .......... .......... .......... .......... .......... 83%  113M 0s
 40400K .......... .......... .......... .......... .......... 83% 84.2M 0s
 40450K .......... .......... .......... .......... .......... 83% 94.8M 0s
 40500K .......... .......... .......... .......... .......... 83% 99.8M 0s
 40550K .......... .......... .......... .......... .......... 84%  112M 0s
 40600K .......... .......... .......... .......... .......... 84% 79.4M 0s
 40650K .......... .......... .......... .......... .......... 84% 91.1M 0s
 40700K .......... .......... .......... .......... .......... 84%  101M 0s
 40750K .......... .......... .......... .......... .......... 84%  102M 0s
 40800K .......... .......... .......... .......... .......... 84% 76.2M 0s
 40850K .......... .......... .......... .......... .......... 84% 98.1M 0s
 40900K .......... .......... .......... .......... .......... 84%  101M 0s
 40950K .......... .......... .......... .......... .......... 84% 1.13M 0s
 41000K .......... .......... .......... .......... .......... 84% 95.3M 0s
 41050K .......... .......... .......... .......... .......... 85% 78.4M 0s
 41100K .......... .......... .......... .......... .......... 85% 86.7M 0s
 41150K .......... .......... .......... .......... .......... 85% 99.3M 0s
 41200K .......... .......... .......... .......... .......... 85% 82.9M 0s
 41250K .......... .......... .......... .......... .......... 85%  117M 0s
 41300K .......... .......... .......... .......... .......... 85%  114M 0s
 41350K .......... .......... .......... .......... .......... 85%  117M 0s
 41400K .......... .......... .......... .......... .......... 85% 99.2M 0s
 41450K .......... .......... .......... .......... .......... 85%  112M 0s
 41500K .......... .......... .......... .......... .......... 86%  114M 0s
 41550K .......... .......... .......... .......... .......... 86%  122M 0s
 41600K .......... .......... .......... .......... .......... 86% 95.1M 0s
 41650K .......... .......... .......... .......... .......... 86%  117M 0s
 41700K .......... .......... .......... .......... .......... 86%  120M 0s
 41750K .......... .......... .......... .......... .......... 86%  128M 0s
 41800K .......... .......... .......... .......... .......... 86%  119M 0s
 41850K .......... .......... .......... .......... .......... 86%  119M 0s
 41900K .......... .......... .......... .......... .......... 86%  125M 0s
 41950K .......... .......... .......... .......... .......... 86%  121M 0s
 42000K .......... .......... .......... .......... .......... 87% 96.7M 0s
 42050K .......... .......... .......... .......... .......... 87%  122M 0s
 42100K .......... .......... .......... .......... .......... 87%  122M 0s
 42150K .......... .......... .......... .......... .......... 87%  111M 0s
 42200K .......... .......... .......... .......... .......... 87% 99.5M 0s
 42250K .......... .......... .......... .......... .......... 87%  121M 0s
 42300K .......... .......... .......... .......... .......... 87%  113M 0s
 42350K .......... .......... .......... .......... .......... 87%  122M 0s
 42400K .......... .......... .......... .......... .......... 87% 99.0M 0s
 42450K .......... .......... .......... .......... .......... 88%  118M 0s
 42500K .......... .......... .......... .......... .......... 88%  111M 0s
 42550K .......... .......... .......... .......... .......... 88%  122M 0s
 42600K .......... .......... .......... .......... .......... 88% 94.9M 0s
 42650K .......... .......... .......... .......... .......... 88%  122M 0s
 42700K .......... .......... .......... .......... .......... 88%  121M 0s
 42750K .......... .......... .......... .......... .......... 88%  120M 0s
 42800K .......... .......... .......... .......... .......... 88% 96.8M 0s
 42850K .......... .......... .......... .......... .......... 88%  124M 0s
 42900K .......... .......... .......... .......... .......... 88%  117M 0s
 42950K .......... .......... .......... .......... .......... 89%  131M 0s
 43000K .......... .......... .......... .......... .......... 89%  106M 0s
 43050K .......... .......... .......... .......... .......... 89%  124M 0s
 43100K .......... .......... .......... .......... .......... 89%  105M 0s
 43150K .......... .......... .......... .......... .......... 89%  123M 0s
 43200K .......... .......... .......... .......... .......... 89%  115M 0s
 43250K .......... .......... .......... .......... .......... 89%  117M 0s
 43300K .......... .......... .......... .......... .......... 89%  119M 0s
 43350K .......... .......... .......... .......... .......... 89%  124M 0s
 43400K .......... .......... .......... .......... .......... 89%  109M 0s
 43450K .......... .......... .......... .......... .......... 90% 2.43M 0s
 43500K .......... .......... .......... .......... .......... 90% 55.0M 0s
 43550K .......... .......... .......... .......... .......... 90%  108M 0s
 43600K .......... .......... .......... .......... .......... 90% 89.9M 0s
 43650K .......... .......... .......... .......... .......... 90%  120M 0s
 43700K .......... .......... .......... .......... .......... 90%  116M 0s
 43750K .......... .......... .......... .......... .......... 90%  107M 0s
 43800K .......... .......... .......... .......... .......... 90%  120M 0s
 43850K .......... .......... .......... .......... .......... 90%  102M 0s
 43900K .......... .......... .......... .......... .......... 91%  128M 0s
 43950K .......... .......... .......... .......... .......... 91%  118M 0s
 44000K .......... .......... .......... .......... .......... 91% 17.0M 0s
 44050K .......... .......... .......... .......... .......... 91%  107M 0s
 44100K .......... .......... .......... .......... .......... 91%  105M 0s
 44150K .......... .......... .......... .......... .......... 91%  111M 0s
 44200K .......... .......... .......... .......... .......... 91% 79.4M 0s
 44250K .......... .......... .......... .......... .......... 91% 89.9M 0s
 44300K .......... .......... .......... .......... .......... 91%  112M 0s
 44350K .......... .......... .......... .......... .......... 91%  112M 0s
 44400K .......... .......... .......... .......... .......... 92% 85.2M 0s
 44450K .......... .......... .......... .......... .......... 92%  113M 0s
 44500K .......... .......... .......... .......... .......... 92%  101M 0s
 44550K .......... .......... .......... .......... .......... 92%  120M 0s
 44600K .......... .......... .......... .......... .......... 92%  107M 0s
 44650K .......... .......... .......... .......... .......... 92%  112M 0s
 44700K .......... .......... .......... .......... .......... 92%  125M 0s
 44750K .......... .......... .......... .......... .......... 92%  110M 0s
 44800K .......... .......... .......... .......... .......... 92% 98.0M 0s
 44850K .......... .......... .......... .......... .......... 92%  101M 0s
 44900K .......... .......... .......... .......... .......... 93%  109M 0s
 44950K .......... .......... .......... .......... .......... 93%  132M 0s
 45000K .......... .......... .......... .......... .......... 93% 8.36M 0s
 45050K .......... .......... .......... .......... .......... 93% 1.07M 0s
 45100K .......... .......... .......... .......... .......... 93% 90.2M 0s
 45150K .......... .......... .......... .......... .......... 93%  105M 0s
 45200K .......... .......... .......... .......... .......... 93% 81.1M 0s
 45250K .......... .......... .......... .......... .......... 93%  102M 0s
 45300K .......... .......... .......... .......... .......... 93%  103M 0s
 45350K .......... .......... .......... .......... .......... 94%  106M 0s
 45400K .......... .......... .......... .......... .......... 94% 97.9M 0s
 45450K .......... .......... .......... .......... .......... 94%  114M 0s
 45500K .......... .......... .......... .......... .......... 94%  116M 0s
 45550K .......... .......... .......... .......... .......... 94%  109M 0s
 45600K .......... .......... .......... .......... .......... 94% 99.6M 0s
 45650K .......... .......... .......... .......... .......... 94%  128M 0s
 45700K .......... .......... .......... .......... .......... 94%  123M 0s
 45750K .......... .......... .......... .......... .......... 94%  129M 0s
 45800K .......... .......... .......... .......... .......... 94%  111M 0s
 45850K .......... .......... .......... .......... .......... 95%  120M 0s
 45900K .......... .......... .......... .......... .......... 95%  114M 0s
 45950K .......... .......... .......... .......... .......... 95% 83.2M 0s
 46000K .......... .......... .......... .......... .......... 95%  114M 0s
 46050K .......... .......... .......... .......... .......... 95%  108M 0s
 46100K .......... .......... .......... .......... .......... 95%  141M 0s
 46150K .......... .......... .......... .......... .......... 95%  122M 0s
 46200K .......... .......... .......... .......... .......... 95% 96.0M 0s
 46250K .......... .......... .......... .......... .......... 95%  132M 0s
 46300K .......... .......... .......... .......... .......... 95%  107M 0s
 46350K .......... .......... .......... .......... .......... 96%  123M 0s
 46400K .......... .......... .......... .......... .......... 96%  109M 0s
 46450K .......... .......... .......... .......... .......... 96%  122M 0s
 46500K .......... .......... .......... .......... .......... 96%  129M 0s
 46550K .......... .......... .......... .......... .......... 96%  109M 0s
 46600K .......... .......... .......... .......... .......... 96%  112M 0s
 46650K .......... .......... .......... .......... .......... 96%  131M 0s
 46700K .......... .......... .......... .......... .......... 96%  113M 0s
 46750K .......... .......... .......... .......... .......... 96%  118M 0s
 46800K .......... .......... .......... .......... .......... 97% 97.9M 0s
 46850K .......... .......... .......... .......... .......... 97%  119M 0s
 46900K .......... .......... .......... .......... .......... 97%  120M 0s
 46950K .......... .......... .......... .......... .......... 97%  105M 0s
 47000K .......... .......... .......... .......... .......... 97%  103M 0s
 47050K .......... .......... .......... .......... .......... 97%  110M 0s
 47100K .......... .......... .......... .......... .......... 97%  119M 0s
 47150K .......... .......... .......... .......... .......... 97%  111M 0s
 47200K .......... .......... .......... .......... .......... 97% 97.6M 0s
 47250K .......... .......... .......... .......... .......... 97%  113M 0s
 47300K .......... .......... .......... .......... .......... 98%  125M 0s
 47350K .......... .......... .......... .......... .......... 98%  121M 0s
 47400K .......... .......... .......... .......... .......... 98%  100M 0s
 47450K .......... .......... .......... .......... .......... 98%  125M 0s
 47500K .......... .......... .......... .......... .......... 98%  112M 0s
 47550K .......... .......... .......... .......... .......... 98%  116M 0s
 47600K .......... .......... .......... .......... .......... 98%  110M 0s
 47650K .......... .......... .......... .......... .......... 98%  113M 0s
 47700K .......... .......... .......... .......... .......... 98%  114M 0s
 47750K .......... .......... .......... .......... .......... 98%  111M 0s
 47800K .......... .......... .......... .......... .......... 99%  110M 0s
 47850K .......... .......... .......... .......... .......... 99%  138M 0s
 47900K .......... .......... .......... .......... .......... 99%  114M 0s
 47950K .......... .......... .......... .......... .......... 99%  123M 0s
 48000K .......... .......... .......... .......... .......... 99% 91.9M 0s
 48050K .......... .......... .......... .......... .......... 99% 2.16M 0s
 48100K .......... .......... .......... .......... .......... 99% 91.9M 0s
 48150K .......... .......... .......... .......... .......... 99% 98.6M 0s
 48200K .......... .......... .......... .......... .......... 99%  103M 0s
 48250K .......... .......... .......... .......... ....      100%  102M=2.0s

2023-11-28 19:35:03 (23.5 MB/s) - ‘//lakehouse/default/Files/stockhistory/raw/tar/stockhistory-2023-2024.tgz’ saved [49453874/49453874]

./
./2023/
./2024/
./2024/01/
./2024/02/
./2024/03/
./2024/04/
./2024/05/
./2024/06/
./2024/07/
./2024/08/
./2024/09/
./2024/10/
./2024/11/
./2024/12/
./2024/12/Stocks-2024-12-01.csv
./2024/12/Stocks-2024-12-02.csv
./2024/12/Stocks-2024-12-03.csv
./2024/12/Stocks-2024-12-04.csv
./2024/12/Stocks-2024-12-05.csv
./2024/12/Stocks-2024-12-06.csv
./2024/12/Stocks-2024-12-07.csv
./2024/12/Stocks-2024-12-08.csv
./2024/12/Stocks-2024-12-09.csv
./2024/12/Stocks-2024-12-10.csv
./2024/12/Stocks-2024-12-11.csv
./2024/12/Stocks-2024-12-12.csv
./2024/12/Stocks-2024-12-13.csv
./2024/12/Stocks-2024-12-14.csv
./2024/12/Stocks-2024-12-15.csv
./2024/12/Stocks-2024-12-16.csv
./2024/12/Stocks-2024-12-17.csv
./2024/12/Stocks-2024-12-18.csv
./2024/12/Stocks-2024-12-19.csv
./2024/12/Stocks-2024-12-20.csv
./2024/12/Stocks-2024-12-21.csv
./2024/12/Stocks-2024-12-22.csv
./2024/12/Stocks-2024-12-23.csv
./2024/12/Stocks-2024-12-24.csv
./2024/12/Stocks-2024-12-25.csv
./2024/12/Stocks-2024-12-26.csv
./2024/12/Stocks-2024-12-27.csv
./2024/12/Stocks-2024-12-28.csv
./2024/12/Stocks-2024-12-29.csv
./2024/12/Stocks-2024-12-30.csv
./2024/12/Stocks-2024-12-31.csv
./2024/11/Stocks-2024-11-01.csv
./2024/11/Stocks-2024-11-02.csv
./2024/11/Stocks-2024-11-03.csv
./2024/11/Stocks-2024-11-04.csv
./2024/11/Stocks-2024-11-05.csv
./2024/11/Stocks-2024-11-06.csv
./2024/11/Stocks-2024-11-07.csv
./2024/11/Stocks-2024-11-08.csv
./2024/11/Stocks-2024-11-09.csv
./2024/11/Stocks-2024-11-10.csv
./2024/11/Stocks-2024-11-11.csv
./2024/11/Stocks-2024-11-12.csv
./2024/11/Stocks-2024-11-13.csv
./2024/11/Stocks-2024-11-14.csv
./2024/11/Stocks-2024-11-15.csv
./2024/11/Stocks-2024-11-16.csv
./2024/11/Stocks-2024-11-17.csv
./2024/11/Stocks-2024-11-18.csv
./2024/11/Stocks-2024-11-19.csv
./2024/11/Stocks-2024-11-20.csv
./2024/11/Stocks-2024-11-21.csv
./2024/11/Stocks-2024-11-22.csv
./2024/11/Stocks-2024-11-23.csv
./2024/11/Stocks-2024-11-24.csv
./2024/11/Stocks-2024-11-25.csv
./2024/11/Stocks-2024-11-26.csv
./2024/11/Stocks-2024-11-27.csv
./2024/11/Stocks-2024-11-28.csv
./2024/11/Stocks-2024-11-29.csv
./2024/11/Stocks-2024-11-30.csv
./2024/10/Stocks-2024-10-01.csv
./2024/10/Stocks-2024-10-02.csv
./2024/10/Stocks-2024-10-03.csv
./2024/10/Stocks-2024-10-04.csv
./2024/10/Stocks-2024-10-05.csv
./2024/10/Stocks-2024-10-06.csv
./2024/10/Stocks-2024-10-07.csv
./2024/10/Stocks-2024-10-08.csv
./2024/10/Stocks-2024-10-09.csv
./2024/10/Stocks-2024-10-10.csv
./2024/10/Stocks-2024-10-11.csv
./2024/10/Stocks-2024-10-12.csv
./2024/10/Stocks-2024-10-13.csv
./2024/10/Stocks-2024-10-14.csv
./2024/10/Stocks-2024-10-15.csv
./2024/10/Stocks-2024-10-16.csv
./2024/10/Stocks-2024-10-17.csv
./2024/10/Stocks-2024-10-18.csv
./2024/10/Stocks-2024-10-19.csv
./2024/10/Stocks-2024-10-20.csv
./2024/10/Stocks-2024-10-21.csv
./2024/10/Stocks-2024-10-22.csv
./2024/10/Stocks-2024-10-23.csv
./2024/10/Stocks-2024-10-24.csv
./2024/10/Stocks-2024-10-25.csv
./2024/10/Stocks-2024-10-26.csv
./2024/10/Stocks-2024-10-27.csv
./2024/10/Stocks-2024-10-28.csv
./2024/10/Stocks-2024-10-29.csv
./2024/10/Stocks-2024-10-30.csv
./2024/10/Stocks-2024-10-31.csv
./2024/09/Stocks-2024-09-01.csv
./2024/09/Stocks-2024-09-02.csv
./2024/09/Stocks-2024-09-03.csv
./2024/09/Stocks-2024-09-04.csv
./2024/09/Stocks-2024-09-05.csv
./2024/09/Stocks-2024-09-06.csv
./2024/09/Stocks-2024-09-07.csv
./2024/09/Stocks-2024-09-08.csv
./2024/09/Stocks-2024-09-09.csv
./2024/09/Stocks-2024-09-10.csv
./2024/09/Stocks-2024-09-11.csv
./2024/09/Stocks-2024-09-12.csv
./2024/09/Stocks-2024-09-13.csv
./2024/09/Stocks-2024-09-14.csv
./2024/09/Stocks-2024-09-15.csv
./2024/09/Stocks-2024-09-16.csv
./2024/09/Stocks-2024-09-17.csv
./2024/09/Stocks-2024-09-18.csv
./2024/09/Stocks-2024-09-19.csv
./2024/09/Stocks-2024-09-20.csv
./2024/09/Stocks-2024-09-21.csv
./2024/09/Stocks-2024-09-22.csv
./2024/09/Stocks-2024-09-23.csv
./2024/09/Stocks-2024-09-24.csv
./2024/09/Stocks-2024-09-25.csv
./2024/09/Stocks-2024-09-26.csv
./2024/09/Stocks-2024-09-27.csv
./2024/09/Stocks-2024-09-28.csv
./2024/09/Stocks-2024-09-29.csv
./2024/09/Stocks-2024-09-30.csv
./2024/08/Stocks-2024-08-01.csv
./2024/08/Stocks-2024-08-02.csv
./2024/08/Stocks-2024-08-03.csv
./2024/08/Stocks-2024-08-04.csv
./2024/08/Stocks-2024-08-05.csv
./2024/08/Stocks-2024-08-06.csv
./2024/08/Stocks-2024-08-07.csv
./2024/08/Stocks-2024-08-08.csv
./2024/08/Stocks-2024-08-09.csv
./2024/08/Stocks-2024-08-10.csv
./2024/08/Stocks-2024-08-11.csv
./2024/08/Stocks-2024-08-12.csv
./2024/08/Stocks-2024-08-13.csv
./2024/08/Stocks-2024-08-14.csv
./2024/08/Stocks-2024-08-15.csv
./2024/08/Stocks-2024-08-16.csv
./2024/08/Stocks-2024-08-17.csv
./2024/08/Stocks-2024-08-18.csv
./2024/08/Stocks-2024-08-19.csv
./2024/08/Stocks-2024-08-20.csv
./2024/08/Stocks-2024-08-21.csv
./2024/08/Stocks-2024-08-22.csv
./2024/08/Stocks-2024-08-23.csv
./2024/08/Stocks-2024-08-24.csv
./2024/08/Stocks-2024-08-25.csv
./2024/08/Stocks-2024-08-26.csv
./2024/08/Stocks-2024-08-27.csv
./2024/08/Stocks-2024-08-28.csv
./2024/08/Stocks-2024-08-29.csv
./2024/08/Stocks-2024-08-30.csv
./2024/08/Stocks-2024-08-31.csv
./2024/07/Stocks-2024-07-01.csv
./2024/07/Stocks-2024-07-02.csv
./2024/07/Stocks-2024-07-03.csv
./2024/07/Stocks-2024-07-04.csv
./2024/07/Stocks-2024-07-05.csv
./2024/07/Stocks-2024-07-06.csv
./2024/07/Stocks-2024-07-07.csv
./2024/07/Stocks-2024-07-08.csv
./2024/07/Stocks-2024-07-09.csv
./2024/07/Stocks-2024-07-10.csv
./2024/07/Stocks-2024-07-11.csv
./2024/07/Stocks-2024-07-12.csv
./2024/07/Stocks-2024-07-13.csv
./2024/07/Stocks-2024-07-14.csv
./2024/07/Stocks-2024-07-15.csv
./2024/07/Stocks-2024-07-16.csv
./2024/07/Stocks-2024-07-17.csv
./2024/07/Stocks-2024-07-18.csv
./2024/07/Stocks-2024-07-19.csv
./2024/07/Stocks-2024-07-20.csv
./2024/07/Stocks-2024-07-21.csv
./2024/07/Stocks-2024-07-22.csv
./2024/07/Stocks-2024-07-23.csv
./2024/07/Stocks-2024-07-24.csv
./2024/07/Stocks-2024-07-25.csv
./2024/07/Stocks-2024-07-26.csv
./2024/07/Stocks-2024-07-27.csv
./2024/07/Stocks-2024-07-28.csv
./2024/07/Stocks-2024-07-29.csv
./2024/07/Stocks-2024-07-30.csv
./2024/07/Stocks-2024-07-31.csv
./2024/06/Stocks-2024-06-01.csv
./2024/06/Stocks-2024-06-02.csv
./2024/06/Stocks-2024-06-03.csv
./2024/06/Stocks-2024-06-04.csv
./2024/06/Stocks-2024-06-05.csv
./2024/06/Stocks-2024-06-06.csv
./2024/06/Stocks-2024-06-07.csv
./2024/06/Stocks-2024-06-08.csv
./2024/06/Stocks-2024-06-09.csv
./2024/06/Stocks-2024-06-10.csv
./2024/06/Stocks-2024-06-11.csv
./2024/06/Stocks-2024-06-12.csv
./2024/06/Stocks-2024-06-13.csv
./2024/06/Stocks-2024-06-14.csv
./2024/06/Stocks-2024-06-15.csv
./2024/06/Stocks-2024-06-16.csv
./2024/06/Stocks-2024-06-17.csv
./2024/06/Stocks-2024-06-18.csv
./2024/06/Stocks-2024-06-19.csv
./2024/06/Stocks-2024-06-20.csv
./2024/06/Stocks-2024-06-21.csv
./2024/06/Stocks-2024-06-22.csv
./2024/06/Stocks-2024-06-23.csv
./2024/06/Stocks-2024-06-24.csv
./2024/06/Stocks-2024-06-25.csv
./2024/06/Stocks-2024-06-26.csv
./2024/06/Stocks-2024-06-27.csv
./2024/06/Stocks-2024-06-28.csv
./2024/06/Stocks-2024-06-29.csv
./2024/06/Stocks-2024-06-30.csv
./2024/05/Stocks-2024-05-01.csv
./2024/05/Stocks-2024-05-02.csv
./2024/05/Stocks-2024-05-03.csv
./2024/05/Stocks-2024-05-04.csv
./2024/05/Stocks-2024-05-05.csv
./2024/05/Stocks-2024-05-06.csv
./2024/05/Stocks-2024-05-07.csv
./2024/05/Stocks-2024-05-08.csv
./2024/05/Stocks-2024-05-09.csv
./2024/05/Stocks-2024-05-10.csv
./2024/05/Stocks-2024-05-11.csv
./2024/05/Stocks-2024-05-12.csv
./2024/05/Stocks-2024-05-13.csv
./2024/05/Stocks-2024-05-14.csv
./2024/05/Stocks-2024-05-15.csv
./2024/05/Stocks-2024-05-16.csv
./2024/05/Stocks-2024-05-17.csv
./2024/05/Stocks-2024-05-18.csv
./2024/05/Stocks-2024-05-19.csv
./2024/05/Stocks-2024-05-20.csv
./2024/05/Stocks-2024-05-21.csv
./2024/05/Stocks-2024-05-22.csv
./2024/05/Stocks-2024-05-23.csv
./2024/05/Stocks-2024-05-24.csv
./2024/05/Stocks-2024-05-25.csv
./2024/05/Stocks-2024-05-26.csv
./2024/05/Stocks-2024-05-27.csv
./2024/05/Stocks-2024-05-28.csv
./2024/05/Stocks-2024-05-29.csv
./2024/05/Stocks-2024-05-30.csv
./2024/05/Stocks-2024-05-31.csv
./2024/04/Stocks-2024-04-01.csv
./2024/04/Stocks-2024-04-02.csv
./2024/04/Stocks-2024-04-03.csv
./2024/04/Stocks-2024-04-04.csv
./2024/04/Stocks-2024-04-05.csv
./2024/04/Stocks-2024-04-06.csv
./2024/04/Stocks-2024-04-07.csv
./2024/04/Stocks-2024-04-08.csv
./2024/04/Stocks-2024-04-09.csv
./2024/04/Stocks-2024-04-10.csv
./2024/04/Stocks-2024-04-11.csv
./2024/04/Stocks-2024-04-12.csv
./2024/04/Stocks-2024-04-13.csv
./2024/04/Stocks-2024-04-14.csv
./2024/04/Stocks-2024-04-15.csv
./2024/04/Stocks-2024-04-16.csv
./2024/04/Stocks-2024-04-17.csv
./2024/04/Stocks-2024-04-18.csv
./2024/04/Stocks-2024-04-19.csv
./2024/04/Stocks-2024-04-20.csv
./2024/04/Stocks-2024-04-21.csv
./2024/04/Stocks-2024-04-22.csv
./2024/04/Stocks-2024-04-23.csv
./2024/04/Stocks-2024-04-24.csv
./2024/04/Stocks-2024-04-25.csv
./2024/04/Stocks-2024-04-26.csv
./2024/04/Stocks-2024-04-27.csv
./2024/04/Stocks-2024-04-28.csv
./2024/04/Stocks-2024-04-29.csv
./2024/04/Stocks-2024-04-30.csv
./2024/03/Stocks-2024-03-01.csv
./2024/03/Stocks-2024-03-02.csv
./2024/03/Stocks-2024-03-03.csv
./2024/03/Stocks-2024-03-04.csv
./2024/03/Stocks-2024-03-05.csv
./2024/03/Stocks-2024-03-06.csv
./2024/03/Stocks-2024-03-07.csv
./2024/03/Stocks-2024-03-08.csv
./2024/03/Stocks-2024-03-09.csv
./2024/03/Stocks-2024-03-10.csv
./2024/03/Stocks-2024-03-11.csv
./2024/03/Stocks-2024-03-12.csv
./2024/03/Stocks-2024-03-13.csv
./2024/03/Stocks-2024-03-14.csv
./2024/03/Stocks-2024-03-15.csv
./2024/03/Stocks-2024-03-16.csv
./2024/03/Stocks-2024-03-17.csv
./2024/03/Stocks-2024-03-18.csv
./2024/03/Stocks-2024-03-19.csv
./2024/03/Stocks-2024-03-20.csv
./2024/03/Stocks-2024-03-21.csv
./2024/03/Stocks-2024-03-22.csv
./2024/03/Stocks-2024-03-23.csv
./2024/03/Stocks-2024-03-24.csv
./2024/03/Stocks-2024-03-25.csv
./2024/03/Stocks-2024-03-26.csv
./2024/03/Stocks-2024-03-27.csv
./2024/03/Stocks-2024-03-28.csv
./2024/03/Stocks-2024-03-29.csv
./2024/03/Stocks-2024-03-30.csv
./2024/03/Stocks-2024-03-31.csv
./2024/02/Stocks-2024-02-01.csv
./2024/02/Stocks-2024-02-02.csv
./2024/02/Stocks-2024-02-03.csv
./2024/02/Stocks-2024-02-04.csv
./2024/02/Stocks-2024-02-05.csv
./2024/02/Stocks-2024-02-06.csv
./2024/02/Stocks-2024-02-07.csv
./2024/02/Stocks-2024-02-08.csv
./2024/02/Stocks-2024-02-09.csv
./2024/02/Stocks-2024-02-10.csv
./2024/02/Stocks-2024-02-11.csv
./2024/02/Stocks-2024-02-12.csv
./2024/02/Stocks-2024-02-13.csv
./2024/02/Stocks-2024-02-14.csv
./2024/02/Stocks-2024-02-15.csv
./2024/02/Stocks-2024-02-16.csv
./2024/02/Stocks-2024-02-17.csv
./2024/02/Stocks-2024-02-18.csv
./2024/02/Stocks-2024-02-19.csv
./2024/02/Stocks-2024-02-20.csv
./2024/02/Stocks-2024-02-21.csv
./2024/02/Stocks-2024-02-22.csv
./2024/02/Stocks-2024-02-23.csv
./2024/02/Stocks-2024-02-24.csv
./2024/02/Stocks-2024-02-25.csv
./2024/02/Stocks-2024-02-26.csv
./2024/02/Stocks-2024-02-27.csv
./2024/02/Stocks-2024-02-28.csv
./2024/02/Stocks-2024-02-29.csv
./2024/01/Stocks-2024-01-01.csv
./2024/01/Stocks-2024-01-02.csv
./2024/01/Stocks-2024-01-03.csv
./2024/01/Stocks-2024-01-04.csv
./2024/01/Stocks-2024-01-05.csv
./2024/01/Stocks-2024-01-06.csv
./2024/01/Stocks-2024-01-07.csv
./2024/01/Stocks-2024-01-08.csv
./2024/01/Stocks-2024-01-09.csv
./2024/01/Stocks-2024-01-10.csv
./2024/01/Stocks-2024-01-11.csv
./2024/01/Stocks-2024-01-12.csv
./2024/01/Stocks-2024-01-13.csv
./2024/01/Stocks-2024-01-14.csv
./2024/01/Stocks-2024-01-15.csv
./2024/01/Stocks-2024-01-16.csv
./2024/01/Stocks-2024-01-17.csv
./2024/01/Stocks-2024-01-18.csv
./2024/01/Stocks-2024-01-19.csv
./2024/01/Stocks-2024-01-20.csv
./2024/01/Stocks-2024-01-21.csv
./2024/01/Stocks-2024-01-22.csv
./2024/01/Stocks-2024-01-23.csv
./2024/01/Stocks-2024-01-24.csv
./2024/01/Stocks-2024-01-25.csv
./2024/01/Stocks-2024-01-26.csv
./2024/01/Stocks-2024-01-27.csv
./2024/01/Stocks-2024-01-28.csv
./2024/01/Stocks-2024-01-29.csv
./2024/01/Stocks-2024-01-30.csv
./2024/01/Stocks-2024-01-31.csv
./2023/01/
./2023/02/
./2023/03/
./2023/04/
./2023/05/
./2023/06/
./2023/07/
./2023/08/
./2023/09/
./2023/10/
./2023/11/
./2023/12/
./2023/12/Stocks-2023-12-01.csv
./2023/12/Stocks-2023-12-02.csv
./2023/12/Stocks-2023-12-03.csv
./2023/12/Stocks-2023-12-04.csv
./2023/12/Stocks-2023-12-05.csv
./2023/12/Stocks-2023-12-06.csv
./2023/12/Stocks-2023-12-07.csv
./2023/12/Stocks-2023-12-08.csv
./2023/12/Stocks-2023-12-09.csv
./2023/12/Stocks-2023-12-10.csv
./2023/12/Stocks-2023-12-11.csv
./2023/12/Stocks-2023-12-12.csv
./2023/12/Stocks-2023-12-13.csv
./2023/12/Stocks-2023-12-14.csv
./2023/12/Stocks-2023-12-15.csv
./2023/12/Stocks-2023-12-16.csv
./2023/12/Stocks-2023-12-17.csv
./2023/12/Stocks-2023-12-18.csv
./2023/12/Stocks-2023-12-19.csv
./2023/12/Stocks-2023-12-20.csv
./2023/12/Stocks-2023-12-21.csv
./2023/12/Stocks-2023-12-22.csv
./2023/12/Stocks-2023-12-23.csv
./2023/12/Stocks-2023-12-24.csv
./2023/12/Stocks-2023-12-25.csv
./2023/12/Stocks-2023-12-26.csv
./2023/12/Stocks-2023-12-27.csv
./2023/12/Stocks-2023-12-28.csv
./2023/12/Stocks-2023-12-29.csv
./2023/12/Stocks-2023-12-30.csv
./2023/12/Stocks-2023-12-31.csv
./2023/11/Stocks-2023-11-01.csv
./2023/11/Stocks-2023-11-02.csv
./2023/11/Stocks-2023-11-03.csv
./2023/11/Stocks-2023-11-04.csv
./2023/11/Stocks-2023-11-05.csv
./2023/11/Stocks-2023-11-06.csv
./2023/11/Stocks-2023-11-07.csv
./2023/11/Stocks-2023-11-08.csv
./2023/11/Stocks-2023-11-09.csv
./2023/11/Stocks-2023-11-10.csv
./2023/11/Stocks-2023-11-11.csv
./2023/11/Stocks-2023-11-12.csv
./2023/11/Stocks-2023-11-13.csv
./2023/11/Stocks-2023-11-14.csv
./2023/11/Stocks-2023-11-15.csv
./2023/11/Stocks-2023-11-16.csv
./2023/11/Stocks-2023-11-17.csv
./2023/11/Stocks-2023-11-18.csv
./2023/11/Stocks-2023-11-19.csv
./2023/11/Stocks-2023-11-20.csv
./2023/11/Stocks-2023-11-21.csv
./2023/11/Stocks-2023-11-22.csv
./2023/11/Stocks-2023-11-23.csv
./2023/11/Stocks-2023-11-24.csv
./2023/11/Stocks-2023-11-25.csv
./2023/11/Stocks-2023-11-26.csv
./2023/11/Stocks-2023-11-27.csv
./2023/11/Stocks-2023-11-28.csv
./2023/11/Stocks-2023-11-29.csv
./2023/11/Stocks-2023-11-30.csv
./2023/10/Stocks-2023-10-01.csv
./2023/10/Stocks-2023-10-02.csv
./2023/10/Stocks-2023-10-03.csv
./2023/10/Stocks-2023-10-04.csv
./2023/10/Stocks-2023-10-05.csv
./2023/10/Stocks-2023-10-06.csv
./2023/10/Stocks-2023-10-07.csv
./2023/10/Stocks-2023-10-08.csv
./2023/10/Stocks-2023-10-09.csv
./2023/10/Stocks-2023-10-10.csv
./2023/10/Stocks-2023-10-11.csv
./2023/10/Stocks-2023-10-12.csv
./2023/10/Stocks-2023-10-13.csv
./2023/10/Stocks-2023-10-14.csv
./2023/10/Stocks-2023-10-15.csv
./2023/10/Stocks-2023-10-16.csv
./2023/10/Stocks-2023-10-17.csv
./2023/10/Stocks-2023-10-18.csv
./2023/10/Stocks-2023-10-19.csv
./2023/10/Stocks-2023-10-20.csv
./2023/10/Stocks-2023-10-21.csv
./2023/10/Stocks-2023-10-22.csv
./2023/10/Stocks-2023-10-23.csv
./2023/10/Stocks-2023-10-24.csv
./2023/10/Stocks-2023-10-25.csv
./2023/10/Stocks-2023-10-26.csv
./2023/10/Stocks-2023-10-27.csv
./2023/10/Stocks-2023-10-28.csv
./2023/10/Stocks-2023-10-29.csv
./2023/10/Stocks-2023-10-30.csv
./2023/10/Stocks-2023-10-31.csv
./2023/09/Stocks-2023-09-01.csv
./2023/09/Stocks-2023-09-02.csv
./2023/09/Stocks-2023-09-03.csv
./2023/09/Stocks-2023-09-04.csv
./2023/09/Stocks-2023-09-05.csv
./2023/09/Stocks-2023-09-06.csv
./2023/09/Stocks-2023-09-07.csv
./2023/09/Stocks-2023-09-08.csv
./2023/09/Stocks-2023-09-09.csv
./2023/09/Stocks-2023-09-10.csv
./2023/09/Stocks-2023-09-11.csv
./2023/09/Stocks-2023-09-12.csv
./2023/09/Stocks-2023-09-13.csv
./2023/09/Stocks-2023-09-14.csv
./2023/09/Stocks-2023-09-15.csv
./2023/09/Stocks-2023-09-16.csv
./2023/09/Stocks-2023-09-17.csv
./2023/09/Stocks-2023-09-18.csv
./2023/09/Stocks-2023-09-19.csv
./2023/09/Stocks-2023-09-20.csv
./2023/09/Stocks-2023-09-21.csv
./2023/09/Stocks-2023-09-22.csv
./2023/09/Stocks-2023-09-23.csv
./2023/09/Stocks-2023-09-24.csv
./2023/09/Stocks-2023-09-25.csv
./2023/09/Stocks-2023-09-26.csv
./2023/09/Stocks-2023-09-27.csv
./2023/09/Stocks-2023-09-28.csv
./2023/09/Stocks-2023-09-29.csv
./2023/09/Stocks-2023-09-30.csv
./2023/08/Stocks-2023-08-01.csv
./2023/08/Stocks-2023-08-02.csv
./2023/08/Stocks-2023-08-03.csv
./2023/08/Stocks-2023-08-04.csv
./2023/08/Stocks-2023-08-05.csv
./2023/08/Stocks-2023-08-06.csv
./2023/08/Stocks-2023-08-07.csv
./2023/08/Stocks-2023-08-08.csv
./2023/08/Stocks-2023-08-09.csv
./2023/08/Stocks-2023-08-10.csv
./2023/08/Stocks-2023-08-11.csv
./2023/08/Stocks-2023-08-12.csv
./2023/08/Stocks-2023-08-13.csv
./2023/08/Stocks-2023-08-14.csv
./2023/08/Stocks-2023-08-15.csv
./2023/08/Stocks-2023-08-16.csv
./2023/08/Stocks-2023-08-17.csv
./2023/08/Stocks-2023-08-18.csv
./2023/08/Stocks-2023-08-19.csv
./2023/08/Stocks-2023-08-20.csv
./2023/08/Stocks-2023-08-21.csv
./2023/08/Stocks-2023-08-22.csv
./2023/08/Stocks-2023-08-23.csv
./2023/08/Stocks-2023-08-24.csv
./2023/08/Stocks-2023-08-25.csv
./2023/08/Stocks-2023-08-26.csv
./2023/08/Stocks-2023-08-27.csv
./2023/08/Stocks-2023-08-28.csv
./2023/08/Stocks-2023-08-29.csv
./2023/08/Stocks-2023-08-30.csv
./2023/08/Stocks-2023-08-31.csv
./2023/07/Stocks-2023-07-01.csv
./2023/07/Stocks-2023-07-02.csv
./2023/07/Stocks-2023-07-03.csv
./2023/07/Stocks-2023-07-04.csv
./2023/07/Stocks-2023-07-05.csv
./2023/07/Stocks-2023-07-06.csv
./2023/07/Stocks-2023-07-07.csv
./2023/07/Stocks-2023-07-08.csv
./2023/07/Stocks-2023-07-09.csv
./2023/07/Stocks-2023-07-10.csv
./2023/07/Stocks-2023-07-11.csv
./2023/07/Stocks-2023-07-12.csv
./2023/07/Stocks-2023-07-13.csv
./2023/07/Stocks-2023-07-14.csv
./2023/07/Stocks-2023-07-15.csv
./2023/07/Stocks-2023-07-16.csv
./2023/07/Stocks-2023-07-17.csv
./2023/07/Stocks-2023-07-18.csv
./2023/07/Stocks-2023-07-19.csv
./2023/07/Stocks-2023-07-20.csv
./2023/07/Stocks-2023-07-21.csv
./2023/07/Stocks-2023-07-22.csv
./2023/07/Stocks-2023-07-23.csv
./2023/07/Stocks-2023-07-24.csv
./2023/07/Stocks-2023-07-25.csv
./2023/07/Stocks-2023-07-26.csv
./2023/07/Stocks-2023-07-27.csv
./2023/07/Stocks-2023-07-28.csv
./2023/07/Stocks-2023-07-29.csv
./2023/07/Stocks-2023-07-30.csv
./2023/07/Stocks-2023-07-31.csv
./2023/06/Stocks-2023-06-01.csv
./2023/06/Stocks-2023-06-02.csv
./2023/06/Stocks-2023-06-03.csv
./2023/06/Stocks-2023-06-04.csv
./2023/06/Stocks-2023-06-05.csv
./2023/06/Stocks-2023-06-06.csv
./2023/06/Stocks-2023-06-07.csv
./2023/06/Stocks-2023-06-08.csv
./2023/06/Stocks-2023-06-09.csv
./2023/06/Stocks-2023-06-10.csv
./2023/06/Stocks-2023-06-11.csv
./2023/06/Stocks-2023-06-12.csv
./2023/06/Stocks-2023-06-13.csv
./2023/06/Stocks-2023-06-14.csv
./2023/06/Stocks-2023-06-15.csv
./2023/06/Stocks-2023-06-16.csv
./2023/06/Stocks-2023-06-17.csv
./2023/06/Stocks-2023-06-18.csv
./2023/06/Stocks-2023-06-19.csv
./2023/06/Stocks-2023-06-20.csv
./2023/06/Stocks-2023-06-21.csv
./2023/06/Stocks-2023-06-22.csv
./2023/06/Stocks-2023-06-23.csv
./2023/06/Stocks-2023-06-24.csv
./2023/06/Stocks-2023-06-25.csv
./2023/06/Stocks-2023-06-26.csv
./2023/06/Stocks-2023-06-27.csv
./2023/06/Stocks-2023-06-28.csv
./2023/06/Stocks-2023-06-29.csv
./2023/06/Stocks-2023-06-30.csv
./2023/05/Stocks-2023-05-01.csv
./2023/05/Stocks-2023-05-02.csv
./2023/05/Stocks-2023-05-03.csv
./2023/05/Stocks-2023-05-04.csv
./2023/05/Stocks-2023-05-05.csv
./2023/05/Stocks-2023-05-06.csv
./2023/05/Stocks-2023-05-07.csv
./2023/05/Stocks-2023-05-08.csv
./2023/05/Stocks-2023-05-09.csv
./2023/05/Stocks-2023-05-10.csv
./2023/05/Stocks-2023-05-11.csv
./2023/05/Stocks-2023-05-12.csv
./2023/05/Stocks-2023-05-13.csv
./2023/05/Stocks-2023-05-14.csv
./2023/05/Stocks-2023-05-15.csv
./2023/05/Stocks-2023-05-16.csv
./2023/05/Stocks-2023-05-17.csv
./2023/05/Stocks-2023-05-18.csv
./2023/05/Stocks-2023-05-19.csv
./2023/05/Stocks-2023-05-20.csv
./2023/05/Stocks-2023-05-21.csv
./2023/05/Stocks-2023-05-22.csv
./2023/05/Stocks-2023-05-23.csv
./2023/05/Stocks-2023-05-24.csv
./2023/05/Stocks-2023-05-25.csv
./2023/05/Stocks-2023-05-26.csv
./2023/05/Stocks-2023-05-27.csv
./2023/05/Stocks-2023-05-28.csv
./2023/05/Stocks-2023-05-29.csv
./2023/05/Stocks-2023-05-30.csv
./2023/05/Stocks-2023-05-31.csv
./2023/04/Stocks-2023-04-01.csv
./2023/04/Stocks-2023-04-02.csv
./2023/04/Stocks-2023-04-03.csv
./2023/04/Stocks-2023-04-04.csv
./2023/04/Stocks-2023-04-05.csv
./2023/04/Stocks-2023-04-06.csv
./2023/04/Stocks-2023-04-07.csv
./2023/04/Stocks-2023-04-08.csv
./2023/04/Stocks-2023-04-09.csv
./2023/04/Stocks-2023-04-10.csv
./2023/04/Stocks-2023-04-11.csv
./2023/04/Stocks-2023-04-12.csv
./2023/04/Stocks-2023-04-13.csv
./2023/04/Stocks-2023-04-14.csv
./2023/04/Stocks-2023-04-15.csv
./2023/04/Stocks-2023-04-16.csv
./2023/04/Stocks-2023-04-17.csv
./2023/04/Stocks-2023-04-18.csv
./2023/04/Stocks-2023-04-19.csv
./2023/04/Stocks-2023-04-20.csv
./2023/04/Stocks-2023-04-21.csv
./2023/04/Stocks-2023-04-22.csv
./2023/04/Stocks-2023-04-23.csv
./2023/04/Stocks-2023-04-24.csv
./2023/04/Stocks-2023-04-25.csv
./2023/04/Stocks-2023-04-26.csv
./2023/04/Stocks-2023-04-27.csv
./2023/04/Stocks-2023-04-28.csv
./2023/04/Stocks-2023-04-29.csv
./2023/04/Stocks-2023-04-30.csv
./2023/03/Stocks-2023-03-01.csv
./2023/03/Stocks-2023-03-02.csv
./2023/03/Stocks-2023-03-03.csv
./2023/03/Stocks-2023-03-04.csv
./2023/03/Stocks-2023-03-05.csv
./2023/03/Stocks-2023-03-06.csv
./2023/03/Stocks-2023-03-07.csv
./2023/03/Stocks-2023-03-08.csv
./2023/03/Stocks-2023-03-09.csv
./2023/03/Stocks-2023-03-10.csv
./2023/03/Stocks-2023-03-11.csv
./2023/03/Stocks-2023-03-12.csv
./2023/03/Stocks-2023-03-13.csv
./2023/03/Stocks-2023-03-14.csv
./2023/03/Stocks-2023-03-15.csv
./2023/03/Stocks-2023-03-16.csv
./2023/03/Stocks-2023-03-17.csv
./2023/03/Stocks-2023-03-18.csv
./2023/03/Stocks-2023-03-19.csv
./2023/03/Stocks-2023-03-20.csv
./2023/03/Stocks-2023-03-21.csv
./2023/03/Stocks-2023-03-22.csv
./2023/03/Stocks-2023-03-23.csv
./2023/03/Stocks-2023-03-24.csv
./2023/03/Stocks-2023-03-25.csv
./2023/03/Stocks-2023-03-26.csv
./2023/03/Stocks-2023-03-27.csv
./2023/03/Stocks-2023-03-28.csv
./2023/03/Stocks-2023-03-29.csv
./2023/03/Stocks-2023-03-30.csv
./2023/03/Stocks-2023-03-31.csv
./2023/02/Stocks-2023-02-01.csv
./2023/02/Stocks-2023-02-02.csv
./2023/02/Stocks-2023-02-03.csv
./2023/02/Stocks-2023-02-04.csv
./2023/02/Stocks-2023-02-05.csv
./2023/02/Stocks-2023-02-06.csv
./2023/02/Stocks-2023-02-07.csv
./2023/02/Stocks-2023-02-08.csv
./2023/02/Stocks-2023-02-09.csv
./2023/02/Stocks-2023-02-10.csv
./2023/02/Stocks-2023-02-11.csv
./2023/02/Stocks-2023-02-12.csv
./2023/02/Stocks-2023-02-13.csv
./2023/02/Stocks-2023-02-14.csv
./2023/02/Stocks-2023-02-15.csv
./2023/02/Stocks-2023-02-16.csv
./2023/02/Stocks-2023-02-17.csv
./2023/02/Stocks-2023-02-18.csv
./2023/02/Stocks-2023-02-19.csv
./2023/02/Stocks-2023-02-20.csv
./2023/02/Stocks-2023-02-21.csv
./2023/02/Stocks-2023-02-22.csv
./2023/02/Stocks-2023-02-23.csv
./2023/02/Stocks-2023-02-24.csv
./2023/02/Stocks-2023-02-25.csv
./2023/02/Stocks-2023-02-26.csv
./2023/02/Stocks-2023-02-27.csv
./2023/02/Stocks-2023-02-28.csv
./2023/01/Stocks-2023-01-01.csv
./2023/01/Stocks-2023-01-02.csv
./2023/01/Stocks-2023-01-03.csv
./2023/01/Stocks-2023-01-04.csv
./2023/01/Stocks-2023-01-05.csv
./2023/01/Stocks-2023-01-06.csv
./2023/01/Stocks-2023-01-07.csv
./2023/01/Stocks-2023-01-08.csv
./2023/01/Stocks-2023-01-09.csv
./2023/01/Stocks-2023-01-10.csv
./2023/01/Stocks-2023-01-11.csv
./2023/01/Stocks-2023-01-12.csv
./2023/01/Stocks-2023-01-13.csv
./2023/01/Stocks-2023-01-14.csv
./2023/01/Stocks-2023-01-15.csv
./2023/01/Stocks-2023-01-16.csv
./2023/01/Stocks-2023-01-17.csv
./2023/01/Stocks-2023-01-18.csv
./2023/01/Stocks-2023-01-19.csv
./2023/01/Stocks-2023-01-20.csv
./2023/01/Stocks-2023-01-21.csv
./2023/01/Stocks-2023-01-22.csv
./2023/01/Stocks-2023-01-23.csv
./2023/01/Stocks-2023-01-24.csv
./2023/01/Stocks-2023-01-25.csv
./2023/01/Stocks-2023-01-26.csv
./2023/01/Stocks-2023-01-27.csv
./2023/01/Stocks-2023-01-28.csv
./2023/01/Stocks-2023-01-29.csv
./2023/01/Stocks-2023-01-30.csv
./2023/01/Stocks-2023-01-31.csv

Step 2: Read the CSV files into a DataFrame¶

In [4]:
# read the CSV files, {year}/{month}/{day}.csv

df_stocks = (
    spark.read.format("csv")
    .option("header", "true")
    .load(f"{DATA_FOLDER}/csv/*/*/*.csv")
)

df_stocks.tail(8)
StatementMeta(, 969b99e8-3fbb-4fd8-83d4-d90942f1c689, 6, Finished, Available)
Out[4]:
[Row(symbol='WHO', price='783.0', timestamp='2023-05-14 23:59:00'),
 Row(symbol='WHAT', price='592.25', timestamp='2023-05-14 23:59:00'),
 Row(symbol='IDK', price='639.0', timestamp='2023-05-14 23:59:00'),
 Row(symbol='WHY', price='626.36', timestamp='2023-05-14 23:59:00'),
 Row(symbol='BCUZ', price='969.7', timestamp='2023-05-14 23:59:00'),
 Row(symbol='TMRW', price='794.55', timestamp='2023-05-14 23:59:00'),
 Row(symbol='TDY', price='868.52', timestamp='2023-05-14 23:59:00'),
 Row(symbol='IDGD', price='809.99', timestamp='2023-05-14 23:59:00')]
In [5]:
# remove all but specified stock symbol
# individual models can be built for each stock

df_stocks = df_stocks.select("*").where(
    'symbol == "' + STOCK_SYMBOL + '"'
)

df_stocks.tail(4)
StatementMeta(, 969b99e8-3fbb-4fd8-83d4-d90942f1c689, 7, Finished, Available)
Out[5]:
[Row(symbol='WHO', price='791.68', timestamp='2023-05-14 23:56:00'),
 Row(symbol='WHO', price='780.36', timestamp='2023-05-14 23:57:00'),
 Row(symbol='WHO', price='785.9', timestamp='2023-05-14 23:58:00'),
 Row(symbol='WHO', price='783.0', timestamp='2023-05-14 23:59:00')]
In [6]:
# strictly speaking, we don't need to sort the dataframe, 
# but it can help for exploration of the data 

df_stocks = df_stocks.sort("timestamp")
df_stocks.tail(4)
StatementMeta(, 969b99e8-3fbb-4fd8-83d4-d90942f1c689, 8, Finished, Available)
Out[6]:
[Row(symbol='WHO', price='528.61', timestamp='2024-12-31 23:56:00'),
 Row(symbol='WHO', price='525.03', timestamp='2024-12-31 23:57:00'),
 Row(symbol='WHO', price='526.71', timestamp='2024-12-31 23:58:00'),
 Row(symbol='WHO', price='514.9', timestamp='2024-12-31 23:59:00')]
In [7]:
# include only historical data when building model

import datetime

currentdate = datetime.datetime.utcnow()
currentdate = currentdate.replace(hour=0, minute=0, second=0, microsecond=0)

# to manually specify a cutoff date in the data, specify the date below:
# currentdate = "2023-11-27 00:00:00"

df_stocks_history = df_stocks.select("*").where(
    'timestamp < "' + str(currentdate) + '"')

df_stocks_history.tail(4)
StatementMeta(, 969b99e8-3fbb-4fd8-83d4-d90942f1c689, 9, Finished, Available)
Out[7]:
[Row(symbol='WHO', price='876.89', timestamp='2023-11-27 23:56:00'),
 Row(symbol='WHO', price='872.61', timestamp='2023-11-27 23:57:00'),
 Row(symbol='WHO', price='874.65', timestamp='2023-11-27 23:58:00'),
 Row(symbol='WHO', price='879.56', timestamp='2023-11-27 23:59:00')]
In [8]:
# convert to a pandas dataframe, and rename the columns to 'ds' and 'y'  
# for time and label/outcome columns

import pandas as pd

dfstocks_pd = df_stocks_history.toPandas()

# rename the columns as expected by Prophet (ds and y)
dfstocks_pd = dfstocks_pd.rename(columns={'timestamp': 'ds'})
dfstocks_pd = dfstocks_pd.rename(columns={'price': 'y'})

# verify max/min timestamps in the dataframe, as the tail/head data may not be in order
print('Min: ', dfstocks_pd['ds'].min())
print('Max: ', dfstocks_pd['ds'].max())
StatementMeta(, 969b99e8-3fbb-4fd8-83d4-d90942f1c689, 10, Finished, Available)
Min:  2023-01-01 00:00:00
Max:  2023-11-27 23:59:00

Step 3: Train the model¶

In developing a model, we'll use Prophet developed by Facebook's Core Data Science team. Prophet is ideal for forecasting time series data. Prophet excels at simplicity, so this is an ideal starting point as it limits any feature engineering and variables.

In [9]:
# Prophet variables

changepoint_prior_scale = 0.05
changepoint_range = 0.95
seasonality_prior_scale = 10
weekly_seasonality = 5
StatementMeta(, 969b99e8-3fbb-4fd8-83d4-d90942f1c689, 11, Finished, Available)
In [10]:
from prophet import Prophet
from prophet.plot import add_changepoints_to_plot

m = Prophet(changepoint_prior_scale = changepoint_prior_scale, 
    changepoint_range = changepoint_range, 
    seasonality_prior_scale = seasonality_prior_scale,
    weekly_seasonality=weekly_seasonality)
m.fit(dfstocks_pd)
future = m.make_future_dataframe(periods=60*24*7, freq='min', include_history = False)
forecast = m.predict(future)
fig = m.plot(forecast)
StatementMeta(, 969b99e8-3fbb-4fd8-83d4-d90942f1c689, 12, Finished, Available)
Disabling yearly seasonality. Run prophet with yearly_seasonality=True to override this.
input tempfile: /tmp/tmpx_vihtqe/qb3s21xt.json
input tempfile: /tmp/tmpx_vihtqe/trlc__us.json
idx 0
running CmdStan, num_threads: None
CmdStan args: ['/home/trusted-service-user/cluster-env/trident_env/lib/python3.10/site-packages/prophet/stan_model/prophet_model.bin', 'random', 'seed=53724', 'data', 'file=/tmp/tmpx_vihtqe/qb3s21xt.json', 'init=/tmp/tmpx_vihtqe/trlc__us.json', 'output', 'file=/tmp/tmpx_vihtqe/prophet_modelq7j578rl/prophet_model-20231128193654.csv', 'method=optimize', 'algorithm=lbfgs', 'iter=10000']
Chain [1] start processing
Chain [1] done processing
19:36:54 - cmdstanpy - INFO - Chain [1] start processing
19:39:20 - cmdstanpy - INFO - Chain [1] done processing
In [11]:
fig = m.plot(forecast)
a = add_changepoints_to_plot(fig.gca(), m, forecast)
StatementMeta(, 969b99e8-3fbb-4fd8-83d4-d90942f1c689, 13, Finished, Available)
In [12]:
fig2 = m.plot_components(forecast)
StatementMeta(, 969b99e8-3fbb-4fd8-83d4-d90942f1c689, 14, Finished, Available)
In [13]:
# show the first few rows of the forecast
# yhat is predicted value of y at the given ds

forecast.head()
StatementMeta(, 969b99e8-3fbb-4fd8-83d4-d90942f1c689, 15, Finished, Available)
Out[13]:
ds trend yhat_lower yhat_upper trend_lower trend_upper additive_terms additive_terms_lower additive_terms_upper daily daily_lower daily_upper weekly weekly_lower weekly_upper multiplicative_terms multiplicative_terms_lower multiplicative_terms_upper yhat
0 2023-11-28 00:00:00 850.832209 727.530092 1009.326073 850.832209 850.832209 23.561510 23.561510 23.561510 -89.809929 -89.809929 -89.809929 113.371439 113.371439 113.371439 0.0 0.0 0.0 874.393719
1 2023-11-28 00:01:00 850.831954 737.926558 1019.525300 850.831954 850.831954 23.066960 23.066960 23.066960 -90.273094 -90.273094 -90.273094 113.340054 113.340054 113.340054 0.0 0.0 0.0 873.898914
2 2023-11-28 00:02:00 850.831698 726.055640 1019.743695 850.831698 850.831698 22.582459 22.582459 22.582459 -90.725785 -90.725785 -90.725785 113.308244 113.308244 113.308244 0.0 0.0 0.0 873.414157
3 2023-11-28 00:03:00 850.831443 731.720294 1012.522697 850.831443 850.831443 22.108060 22.108060 22.108060 -91.167947 -91.167947 -91.167947 113.276007 113.276007 113.276007 0.0 0.0 0.0 872.939503
4 2023-11-28 00:04:00 850.831188 733.006903 1013.515838 850.831188 850.831188 21.643816 21.643816 21.643816 -91.599528 -91.599528 -91.599528 113.243343 113.243343 113.243343 0.0 0.0 0.0 872.475004
In [14]:
import plotly.express as px

fig = px.line(forecast, x='ds', y='yhat')
fig.update_layout(title="Trend of predicted (yhat) over time", showlegend=True)
fig.show()
StatementMeta(, 969b99e8-3fbb-4fd8-83d4-d90942f1c689, 16, Finished, Available)

Step 4: Cross Validate¶

The purpose of cross validation is to simplify the process of separating training and test data. This allows us to test many points in time for accuracy, and also allows us to include all data in our model.

For cross validation, the initial period parameter is used to train the cross validation model, forecasting for the specified horizon. The next validation will occur over the next specified period.

So, if we wanted to validate the most recent 2 weeks, we'd specify the number of days in our training set minus 14 days, then specify a horizon and period of 7 days each. This will result in 2 validation forecasts: one for last week, and one for the week prior.

More information on cross validation is available in the Prophet docs.

In [15]:
# calculate the number of days to validate

from datetime import datetime

minDate = datetime.strptime(dfstocks_pd['ds'].min(), '%Y-%m-%d %H:%M:%S') 
maxDate = datetime.strptime(dfstocks_pd['ds'].max(), '%Y-%m-%d %H:%M:%S') 

numDays = (maxDate - minDate).days
numDaysToValidate = numDays - 14

print(numDaysToValidate)
StatementMeta(, 969b99e8-3fbb-4fd8-83d4-d90942f1c689, 17, Finished, Available)
316
In [16]:
from prophet.diagnostics import cross_validation
from prophet.diagnostics import performance_metrics

df_cv = cross_validation(m, initial=f"{numDaysToValidate} days", period="7 days", horizon="7 days")
StatementMeta(, 969b99e8-3fbb-4fd8-83d4-d90942f1c689, 18, Finished, Available)
Making 2 forecasts with cutoffs between 2023-11-13 23:59:00 and 2023-11-20 23:59:00
  0%|          | 0/2 [00:00<?, ?it/s]
input tempfile: /tmp/tmpx_vihtqe/rh28au_6.json
input tempfile: /tmp/tmpx_vihtqe/yiwxk0xf.json
idx 0
running CmdStan, num_threads: None
CmdStan args: ['/home/trusted-service-user/cluster-env/trident_env/lib/python3.10/site-packages/prophet/stan_model/prophet_model.bin', 'random', 'seed=68077', 'data', 'file=/tmp/tmpx_vihtqe/rh28au_6.json', 'init=/tmp/tmpx_vihtqe/yiwxk0xf.json', 'output', 'file=/tmp/tmpx_vihtqe/prophet_modeljq8yhw_x/prophet_model-20231128193958.csv', 'method=optimize', 'algorithm=lbfgs', 'iter=10000']
Chain [1] start processing
Chain [1] done processing
input tempfile: /tmp/tmpx_vihtqe/i91ycjhf.json
input tempfile: /tmp/tmpx_vihtqe/ntd0vusb.json
idx 0
running CmdStan, num_threads: None
CmdStan args: ['/home/trusted-service-user/cluster-env/trident_env/lib/python3.10/site-packages/prophet/stan_model/prophet_model.bin', 'random', 'seed=7497', 'data', 'file=/tmp/tmpx_vihtqe/i91ycjhf.json', 'init=/tmp/tmpx_vihtqe/ntd0vusb.json', 'output', 'file=/tmp/tmpx_vihtqe/prophet_modelfxp2tma8/prophet_model-20231128194311.csv', 'method=optimize', 'algorithm=lbfgs', 'iter=10000']
Chain [1] start processing
Chain [1] done processing
19:39:58 - cmdstanpy - INFO - Chain [1] start processing
19:42:53 - cmdstanpy - INFO - Chain [1] done processing
19:43:11 - cmdstanpy - INFO - Chain [1] start processing
19:45:56 - cmdstanpy - INFO - Chain [1] done processing
In [17]:
df_cv.tail(4)
StatementMeta(, 969b99e8-3fbb-4fd8-83d4-d90942f1c689, 19, Finished, Available)
Out[17]:
ds yhat yhat_lower yhat_upper y cutoff
20156 2023-11-27 23:56:00 900.506915 750.040613 1045.328524 876.89 2023-11-20 23:59:00
20157 2023-11-27 23:57:00 899.972146 758.399509 1051.470874 872.61 2023-11-20 23:59:00
20158 2023-11-27 23:58:00 899.447196 760.243681 1045.334076 874.65 2023-11-20 23:59:00
20159 2023-11-27 23:59:00 898.932128 750.350050 1050.692995 879.56 2023-11-20 23:59:00
In [18]:
# generate metrics using the default rolling window (10%)

from prophet.diagnostics import performance_metrics
df_p = performance_metrics(df_cv)
df_p.head()
StatementMeta(, 969b99e8-3fbb-4fd8-83d4-d90942f1c689, 20, Finished, Available)
Out[18]:
horizon mse rmse mae mape mdape smape coverage
0 0 days 16:48:00 6167.009558 78.530310 63.174213 0.068276 0.060806 0.069019 0.942956
1 0 days 16:49:00 6171.119103 78.556471 63.212545 0.068321 0.060864 0.069065 0.942956
2 0 days 16:50:00 6175.168024 78.582237 63.253430 0.068371 0.060953 0.069114 0.942956
3 0 days 16:51:00 6180.266741 78.614673 63.303327 0.068431 0.061057 0.069174 0.942956
4 0 days 16:52:00 6186.019853 78.651255 63.347925 0.068485 0.061143 0.069228 0.942956
In [19]:
# generate metrics using all data (100%)

from prophet.diagnostics import performance_metrics
df_p = performance_metrics(df_cv, rolling_window=1)
df_p.head()
StatementMeta(, 969b99e8-3fbb-4fd8-83d4-d90942f1c689, 21, Finished, Available)
Out[19]:
horizon mse rmse mae mape mdape smape coverage
0 7 days 12580.251284 112.161719 90.712569 0.114943 0.089969 0.10911 0.786905
In [20]:
# get the statistics for storing in the model
# this becomes part of the model's metadata

mse = df_p['mse'][0]
mae = df_p['mae'][0]
rmse = df_p['rmse'][0]
mape = df_p['mape'][0]

print('mse:', mse)
print('mae:', mae)
print('rmse:', rmse)
print('mape:', mape)
StatementMeta(, 969b99e8-3fbb-4fd8-83d4-d90942f1c689, 22, Finished, Available)
mse: 12580.251284461425
mae: 90.71256901757745
rmse: 112.16171933623978
mape: 0.11494253209995128
In [21]:
# plot the mean absolute percent error (mape)

from prophet.plot import plot_cross_validation_metric
fig = plot_cross_validation_metric(df_cv, metric='mape')
StatementMeta(, 969b99e8-3fbb-4fd8-83d4-d90942f1c689, 23, Finished, Available)
In [22]:
# plot the standard deviation or root mean square deviation (rmse)

from prophet.plot import plot_cross_validation_metric
fig = plot_cross_validation_metric(df_cv, metric='rmse')
StatementMeta(, 969b99e8-3fbb-4fd8-83d4-d90942f1c689, 24, Finished, Available)
In [23]:
# routine for testing multiple combinations of parameters

# by default we won't run this, but this is a way we can test multiple
# parameters and find the most optimal results

# more info at:
# https://facebook.github.io/prophet/docs/diagnostics.html

import itertools
import numpy as np
import pandas as pd

param_grid = {  
    'changepoint_prior_scale': [0.001, 0.1, 0.5],
    'seasonality_prior_scale': [0.01, 0.1, 1.0, 10.0, 15],
    'weekly_seasonality': [3, 5]
}

test_parameters = False # change to True to run series of tests. 

if test_parameters:
    daysToValidate = numDays - 7

    # generate all combinations of parameters
    all_params = [dict(zip(param_grid.keys(), v)) for v in itertools.product(*param_grid.values())]
    rmses = []  # Ssore the RMSEs for each params here

    # use cross validation to evaluate all parameters
    for params in all_params:
        
        m = Prophet(**params).fit(dfstocks_pd)  # fit model with given params
        df_cv = cross_validation(m, initial=f"{daysToValidate} days", period="7 days", horizon="7 days")
        df_p = performance_metrics(df_cv, rolling_window=1)
        rmses.append(df_p['rmse'].values[0])

    # Find the best parameters
    tuning_results = pd.DataFrame(all_params)
    tuning_results['rmse'] = rmses
    print(tuning_results)
StatementMeta(, 969b99e8-3fbb-4fd8-83d4-d90942f1c689, 25, Finished, Available)

Step 5: Log and load model with MLflow¶

MLflow assists with managing ML workflows. We can create a new experiment for each stock (as an example) and then add each run to the experiment. We can also log all of the parameters and metrics with each run, allowing us to see and compare different models. This is part of our operationalizing process. When the run is logged in the experiment, the run is given a URI that can be used to load the model later; however, it's also possible to interact with MLflow visually or programmatically to load/inspect models.

In [24]:
# setup mlflow with an experiment

import mlflow

EXPERIMENT_NAME = STOCK_SYMBOL + "-stock-prediction"
mlflow.set_experiment(EXPERIMENT_NAME)
StatementMeta(, 969b99e8-3fbb-4fd8-83d4-d90942f1c689, 26, Finished, Available)
2023/11/28 19:46:16 INFO mlflow.tracking.fluent: Experiment with name 'WHO-stock-prediction' does not exist. Creating a new experiment.
Out[24]:
<Experiment: artifact_location='', creation_time=1701200780477, experiment_id='bc2f76aa-65a8-4ec1-b163-25cbdddbdb8d', last_update_time=None, lifecycle_stage='active', name='WHO-stock-prediction', tags={}>
In [25]:
from mlflow.models.signature import infer_signature

model_name = f"{EXPERIMENT_NAME}-model"
with mlflow.start_run() as run:
    mlflow.autolog()

    mlflow.prophet.log_model(m, model_name, registered_model_name=model_name,
        signature=infer_signature(future, forecast))

    mlflow.log_params({"changepoint_prior_scale": changepoint_prior_scale })
    mlflow.log_params({"changepoint_range": changepoint_range })
    mlflow.log_params({"seasonality_prior_scale": seasonality_prior_scale })

    mlflow.log_metrics({"mse":mse})
    mlflow.log_metrics({"mae":mae})
    mlflow.log_metrics({"rmse":rmse})
    mlflow.log_metrics({"mape":mape})

    model_uri = f"runs:/{run.info.run_id}/{model_name}"

    print("Model saved in run %s" % run.info.run_id)
    print(f"Model URI: {model_uri}")
StatementMeta(, 969b99e8-3fbb-4fd8-83d4-d90942f1c689, 27, Finished, Available)
/home/trusted-service-user/cluster-env/trident_env/lib/python3.10/site-packages/_distutils_hack/__init__.py:33: UserWarning:

Setuptools is replacing distutils.

Successfully registered model 'WHO-stock-prediction-model'.
2023/11/28 19:46:32 INFO mlflow.tracking._model_registry.client: Waiting up to 300 seconds for model version to finish creation. Model name: WHO-stock-prediction-model, version 1
Created version '1' of model 'WHO-stock-prediction-model'.
Model saved in run bb0419ef-61f4-44ed-a98e-9112dbd55916
Model URI: runs:/bb0419ef-61f4-44ed-a98e-9112dbd55916/WHO-stock-prediction-model

Step 6: Load the model and generate predictions¶

In this step, we'll load the model from MLflow and create a new prediction for the next week.

Because this is a simulation for demo purposes, we already have the future data (or at least, one possibility of future data as the algorithm is highly random). This allows us to compare what the model predicts vs actual. We'll combine the predicted dataset with the actual dataset, and plot the outcome to compare.

In [26]:
import mlflow

loaded_model = mlflow.prophet.load_model(model_uri)
StatementMeta(, 969b99e8-3fbb-4fd8-83d4-d90942f1c689, 28, Finished, Available)
Downloading artifacts:   0%|          | 0/5 [00:00<?, ?it/s]
StatementMeta(, 969b99e8-3fbb-4fd8-83d4-d90942f1c689, 38, Finished, Available)
StatementMeta(, 969b99e8-3fbb-4fd8-83d4-d90942f1c689, 39, Finished, Available)
In [27]:
# establish begin/end dates for prediction

import datetime
from datetime import timedelta

currentdate = datetime.datetime.utcnow()
currentdate = currentdate.replace(hour=0, minute=0, second=0, microsecond=0)
enddate = currentdate + datetime.timedelta(days=7)

print(f'Beginning of forecast: {currentdate}')
print(f'End of forecast: {enddate}')
StatementMeta(, 969b99e8-3fbb-4fd8-83d4-d90942f1c689, 29, Finished, Available)
Beginning of forecast: 2023-11-28 00:00:00
End of forecast: 2023-12-05 00:00:00
In [28]:
# load all of the 'future' data -- 
# will be used to compare prediction

df_stocks_future = df_stocks.select("*").where(
    'timestamp >= "' + str(currentdate) + '" and ' +
    'timestamp < "' + str(enddate) + '"')

df_stocks_future.tail(4)
StatementMeta(, 969b99e8-3fbb-4fd8-83d4-d90942f1c689, 30, Finished, Available)
Out[28]:
[Row(symbol='WHO', price='846.94', timestamp='2023-12-04 23:56:00'),
 Row(symbol='WHO', price='862.69', timestamp='2023-12-04 23:57:00'),
 Row(symbol='WHO', price='877.17', timestamp='2023-12-04 23:58:00'),
 Row(symbol='WHO', price='870.12', timestamp='2023-12-04 23:59:00')]
In [29]:
import pandas as pd

# create a new dataframe to hold the predictions
# copy the timestamp from the future dataframe for convenience
# this new dataframe should only have timestamps for our prediction, 
# and will be labelled as 'ds'

df_stocks_future_pd = df_stocks_future.toPandas()
dfstocks_predict = df_stocks_future_pd[['timestamp']].copy()

# rename timestamp to ds as expected by prophet
dfstocks_predict = dfstocks_predict.rename(columns={'timestamp': 'ds'})

print('Min: ', dfstocks_predict['ds'].min())
print('Max: ', dfstocks_predict['ds'].max())
dfstocks_predict.head()
StatementMeta(, 969b99e8-3fbb-4fd8-83d4-d90942f1c689, 31, Finished, Available)
Min:  2023-11-28 00:00:00
Max:  2023-12-04 23:59:00
Out[29]:
ds
0 2023-11-28 00:00:00
1 2023-11-28 00:01:00
2 2023-11-28 00:02:00
3 2023-11-28 00:03:00
4 2023-11-28 00:04:00
In [30]:
# optionally, can use make_future_dataframe in Prophet to make a suitable df

test_df = loaded_model.make_future_dataframe(periods=60*24*7, freq='min', include_history = False)
test_df.head()
StatementMeta(, 969b99e8-3fbb-4fd8-83d4-d90942f1c689, 32, Finished, Available)
Out[30]:
ds
0 2023-11-28 00:00:00
1 2023-11-28 00:01:00
2 2023-11-28 00:02:00
3 2023-11-28 00:03:00
4 2023-11-28 00:04:00
In [31]:
# predict by passing in the dataframe with timestamps to forecast

forecast = loaded_model.predict(dfstocks_predict)
forecast.head()
StatementMeta(, 969b99e8-3fbb-4fd8-83d4-d90942f1c689, 33, Finished, Available)
Out[31]:
ds trend yhat_lower yhat_upper trend_lower trend_upper additive_terms additive_terms_lower additive_terms_upper daily daily_lower daily_upper weekly weekly_lower weekly_upper multiplicative_terms multiplicative_terms_lower multiplicative_terms_upper yhat
0 2023-11-28 00:00:00 850.832209 739.287059 1022.666715 850.832209 850.832209 23.561510 23.561510 23.561510 -89.809929 -89.809929 -89.809929 113.371439 113.371439 113.371439 0.0 0.0 0.0 874.393719
1 2023-11-28 00:01:00 850.831954 730.814867 1013.416578 850.831954 850.831954 23.066960 23.066960 23.066960 -90.273094 -90.273094 -90.273094 113.340054 113.340054 113.340054 0.0 0.0 0.0 873.898914
2 2023-11-28 00:02:00 850.831698 731.017916 1023.975112 850.831698 850.831698 22.582459 22.582459 22.582459 -90.725785 -90.725785 -90.725785 113.308244 113.308244 113.308244 0.0 0.0 0.0 873.414157
3 2023-11-28 00:03:00 850.831443 725.796840 1017.071866 850.831443 850.831443 22.108060 22.108060 22.108060 -91.167947 -91.167947 -91.167947 113.276007 113.276007 113.276007 0.0 0.0 0.0 872.939503
4 2023-11-28 00:04:00 850.831188 729.194123 1025.868951 850.831188 850.831188 21.643816 21.643816 21.643816 -91.599528 -91.599528 -91.599528 113.243343 113.243343 113.243343 0.0 0.0 0.0 872.475004
In [32]:
# combine forecast and df_stocks_future_pd

df_stocks_future_pd['timestamp'] = pd.to_datetime(df_stocks_future_pd['timestamp'])
forecast['ds'] = pd.to_datetime(forecast['ds'])

metric_df = forecast.set_index('ds')[['yhat']].join(df_stocks_future_pd.set_index('timestamp').price).reset_index()
metric_df.head()
StatementMeta(, 969b99e8-3fbb-4fd8-83d4-d90942f1c689, 34, Finished, Available)
Out[32]:
ds yhat price
0 2023-11-28 00:00:00 874.393719 881.0
1 2023-11-28 00:01:00 873.898914 865.43
2 2023-11-28 00:02:00 873.414157 852.22
3 2023-11-28 00:03:00 872.939503 848.68
4 2023-11-28 00:04:00 872.475004 864.64
In [33]:
import plotly.express as px
import plotly.graph_objects as go

metric_df['ds'] = pd.to_datetime(metric_df['ds'])

fig = go.Figure()
fig.add_trace(go.Scatter(x=metric_df['ds'], y=metric_df['price'], name='Actual', line=dict(color='blue', width=1)))
fig.add_trace(go.Scatter(x=metric_df['ds'], y=metric_df['yhat'], name='Predicted', line=dict(color='red', width=3)))

fig.update_layout(title="Predicted vs Actual", showlegend=True)
fig.show()
StatementMeta(, 969b99e8-3fbb-4fd8-83d4-d90942f1c689, 35, Finished, Available)
In [34]:
# optionally, compute metrics using sklearn to see how they compare to our model

from sklearn.metrics import mean_squared_error, mean_absolute_error

future_mse = round(mean_squared_error(metric_df.price, metric_df.yhat),3)
future_mae = round(mean_absolute_error(metric_df.price, metric_df.yhat),3)
future_rmse = round(mean_squared_error(metric_df.price, metric_df.yhat, squared=False),3)

print(f'mse: {future_mse} (Model: {mse})')
print(f'mae: {future_mae} (Model: {mae})')
print(f'rmse: {future_rmse} (Model: {rmse})')
StatementMeta(, 969b99e8-3fbb-4fd8-83d4-d90942f1c689, 36, Finished, Available)
2023/11/28 19:47:23 INFO mlflow.tracking.fluent: Autologging successfully enabled for sklearn.
mse: 13326.014 (Model: 12580.251284461425)
mae: 94.35 (Model: 90.71256901757745)
rmse: 115.438 (Model: 112.16171933623978)

Additional MLflow¶

MLflow can be interacted with programmatically to load and inspect models. The example below will show all experiments and runs within each experiment.

In [35]:
import mlflow
import pandas as pd

experiments = mlflow.search_experiments()
for exp in experiments:
    print(f'{exp.name} ({exp.experiment_id})')
    runs_df = mlflow.search_runs(exp.experiment_id)
    display(runs_df)
StatementMeta(, 969b99e8-3fbb-4fd8-83d4-d90942f1c689, 37, Finished, Available)
WHO-stock-prediction (bc2f76aa-65a8-4ec1-b163-25cbdddbdb8d)
SynapseWidget(Synapse.DataFrame, 2620bfb5-5f8e-45f4-9256-a4c674851f19)